gorhill / cronexpr Goto Github PK
View Code? Open in Web Editor NEWCron expression parser in Go language (golang)
Cron expression parser in Go language (golang)
most cron implementations authorize the use of leading zeros to improve readbility (and alignment).
When using a task in the form 01 * * * *
, cronexpr complains about bad crontab line: 01 * * * *…
If I remove the leading zero, it works as expected.
Note : I'm using cronexpr through aptible/supercronic
i hope supercronic is not the culprit.
I found these parse error.
syntax error in minute field: 'type'
syntax error in minute field: '['
syntax error in minute field: 'if'
syntax error in minute field: 'SOURCES_PREAMBLE="###'
syntax error in minute field: 'cd'
syntax error in minute field: 'egrep'
Make changes as per https://groups.google.com/d/msg/golang-nuts/la6mB5xG1L4/5V0L2GqF_1oJ
anacron supports looking at the RANDOM_DELAY environment variable and randomly adding between 1 and the value of RANDOM_DELAY minutes to the execute time to help stagger the start of jobs. It would be awesome if cronexpr supported something similar either by looking at the RANDOM_DELAY environment variable OR having something that could be set through the library itself.
More here- http://linux.die.net/man/5/anacrontab
I would be more than happy to implement this w/tests if the PR would be welcome.
Hi,
when parsing the cron expression */60 * * * *
, the tool loops infinitely instead of returning an error or something.
Why using panic instead of return error? because it will break all application if MustParse
function got error.
func MustParse(cronLine string) *Expression {
expr, err := Parse(cronLine)
if err != nil {
panic(err)
}
return expr
}
CMIIW, I prefer like this.
func MustParse(cronLine string) (*Expression, error) {
expr, err := Parse(cronLine)
if err != nil {
return nil, err
}
return expr,nil
}
step to reproduce:
1.get first schedule time
schedule= 2 02 * * * *
fromTime=2016-03-12 02:03:00 -0800 PST
call Next() return: 2016-03-13T01:02:00-08:00
2. get next schedule time.
use the Next() return time as new fromTime: 2016-03-13T01:02:00-08:00
call Next() again ,and return the same value as new fromTime: 2016-03-13T01:02:00-08:00
Hi,
I'm new to the world of GoLang, so this may be a unusual request but I wonder whether we can make the fields within type Expression
exported.
I actually need to analyse a cron by stepping over the arrays of accepted values this library has generated to determine whether, given a duration, we're still within a time period.
There's no package-level documentation: http://godoc.org/github.com/gorhill/cronexpression
At a minimum, the package comment should include a first sentence synopsis.
// Package cronexpression parses cron time expressions.
package conexpression
Edit: There's a lot of doc in the readme that should probably pulled into the code so that it's readable in various Go tools.
I think the documentation should state whether you can have a range + list.
eg.
1-3,4,5-6
cronExpression= "*/5 * * * *"<-- this is every 5 minutes
prints out from log:
now=2017-03-25 15:38:11.667843072 -0700 PDT next_schedule=[2017-03-25 15:40:00 -0700 PDT] sec_diff=109" <-- 109 secs?
e, err = cronexpr.Parse(aws.StringValue(cronExpression))
base := time.Now()
next := e.NextN(base, 1)
// normalize before subtraction to Unix Time
d := int(next[0].Unix() - base.Unix())
logging.Infof("now=%s next_schedule=%s sec_diff=%d", base, next, d)
For convenience, developer might want to check whether an externally supplied cron expression is valid given the currently supported cron syntax.
This func will not be called automatically internally at the entry point CronExpression.NextTime(), the choice will be left to the developer as to whether he/she wants to incur the overhead cost of validation.
In parsing, global package variable layoutRegexp is changing. It is map, so usage in multiple gorountines causes map concurrent write error.
I'd love to be able to step backwards to see the previous time a cron has fired.
cronexpr.Parse() correctly parses dow (day-of-week) when written as 0-6
or SUN-SAT
– but does NOT correctly parse when written as MON-SUN
or 1-7
We can see that 0
and 7
both resolve to Sunday
, so it should be possible to write expressions as either 0-6
OR 1-7
and have the same result. However- the 1-7
day-of-week does not parse.
Here is an example / reproduction scenario
package main
import (
"fmt"
"time"
"github.com/gorhill/cronexpr"
)
func main() {
t := time.Date(2017, time.July, 18, 13, 47, 0, 0, time.UTC)
for _, dow := range []string{"MON-SUN", "SUN-SAT", "0-6", "1-7"} {
times := cronexpr.MustParse(fmt.Sprintf("* * * * %s", dow)).NextN(t, 8)
if len(times) == 0 {
fmt.Printf("Could NOT parse [%s]\n", dow)
} else {
for i := range times {
fmt.Println(times[i].Format(time.RFC1123))
}
}
}
}
func makeLayoutRegexp(layout, value string) *regexp.Regexp {
layout = strings.Replace(layout, `%value%`, value, -1)
re := layoutRegexp[layout]
if re == nil {
re = regexp.MustCompile(layout)
layoutRegexp[layout] = re
}
return re
}
This code will panic when multi-goroutine calls cronexp.Parse(xx) concurrently.
call stack:
fatal error: concurrent map writes
goroutine 33 [running]:
runtime.throw(0xdc8dbf, 0x15)
/home/work/build_tmp/build/1480301702.549625122/xxxx/go/src/runtime/panic.go:566 +0x95 fp=0xc42005d920 sp=0xc42005d900
runtime.mapassign1(0xca0ae0, 0xc4201c72f0, 0xc42005da60, 0xc42005da58)
/home/work/build_tmp/build/1480301702.549625122/xxxx/go/src/runtime/hashmap.go:458 +0x8ef fp=0xc42005da08 sp=0xc42005d920
github.com/gorhill/cronexpr.makeLayoutRegexp(0xdbeb61, 0x9, 0xdc5f55, 0x12, 0x0)
/home/work/build_tmp/build/1480301702.549625122/xxxx/gopath/src/github.com/gorhill/cronexpr/cronexpr_parse.go:486 +0x141 fp=0xc42005da80 sp=0xc42005da08
github.com/gorhill/cronexpr.genericFieldParse(0xc420362c00, 0x1, 0xdbbdd6, 0x6, 0x0, 0x3b, 0x120ac80, 0x3c, 0x3c, 0xdc5f55, ...)
/home/work/build_tmp/build/1480301702.549625122/xxxx/gopath/src/github.com/gorhill/cronexpr/cronexpr_parse.go:417 +0x22b fp=0xc42005db70 sp=0xc42005da80
github.com/gorhill/cronexpr.genericFieldHandler(0xc420362c00, 0x1, 0xdbbdd6, 0x6, 0x0, 0x3b, 0x120ac80, 0x3c, 0x3c, 0xdc5f55, ...)
/home/work/build_tmp/build/1480301702.549625122/xxxx/gopath/src/github.com/gorhill/cronexpr/cronexpr_parse.go:268 +0x70 fp=0xc42005dcf8 sp=0xc42005db70
github.com/gorhill/cronexpr.(*Expression).secondFieldHandler(0xc4201380e0, 0xc420362c00, 0x1, 0xf, 0xc42149f3b0)
/home/work/build_tmp/build/1480301702.549625122/xxxx/gopath/src/github.com/gorhill/cronexpr/cronexpr_parse.go:213 +0x6c fp=0xc42005dda0 sp=0xc42005dcf8
github.com/gorhill/cronexpr.Parse(0xc421315fa0, 0xe, 0x40f3bb, 0xc4202e9f78, 0x0)
/home/work/build_tmp/build/1480301702.549625122/xxxx/gopath/src/github.com/gorhill/cronexpr/cronexpr.go:90 +0x16b fp=0xc42005de28 sp=0xc42005dda0
I will try to workaround this by call cronexp.Parse() when first start(no other goroutine init). :-) and maybe try to send a pull request.
Current benchmarking results on Kernel Linux 3.5.0-17-generic i5-3570K:
BenchmarkParse 50000 42706 ns/op
BenchmarkNext 100000 18948 ns/op
For fields which commonly default to "*", it should be worth to avoid constructing array of valid values.
e.g. via a GetCronLine()
method or similar
Even though the constructor of an Expression
struct necessarily knows the raw cron expression, it would be useful when passing things around to have just the one struct rather than the struct + the cron expression string, in cases where this is necessary to do.
Would it be possible to change the cronexpr.MustParse() function to return an error rather than panic? If so, I'll gladly submit a PR. Thanks!
on this commit, I found a new error.
seems all the job scheduled on DST day will be scheduled at 3am (fall early). i assume it should be just that missing our jobs fall to early time.
e.g
schedule: 0 14 * * * * timezone: America/Los_Angeles fromTime: 2016-03-12 14:01:00 -0800 PST
reschedule to: 2016-03-13T03:00:00-07:00
in the master version, it is set correct to 2016-03-13T14:00:00-07:00
Hello, tracing a bug via Nomad (which uses this library), I've discovered that the following expression causes a nil pointer exception:
1 15-0 * * 1-5
Digging into the code, it's this:
func (expr *Expression) hourFieldHandler(s string) error {
var err error
expr.hourList, err = genericFieldHandler(s, hourDescriptor)
fmt.Println(genericFieldHandler(s, hourDescriptor))
return err
}
It produces an empty list when trying to parse 15-0
:
func (expr *Expression) hourFieldHandler(s string) error {
var err error
expr.hourList, err = genericFieldHandler(s, hourDescriptor)
fmt.Printf("hour: %v\tparsed: %v\n", s, expr.hourList)
return err
}
hour: 15-0 parsed: []
- this leads to expr.hourList[0]
producing a nil pointer over here: https://github.com/gorhill/cronexpr/blob/master/cronexpr_next.go#L115
Is this syntax supposed to be supported? Your doc says hyphens are.
Here's the stacktrace:
panic: runtime error: index out of range [recovered]
panic: runtime error: index out of range
goroutine 5 [running]:
testing.tRunner.func1(0xc4200bc0f0)
/usr/local/go/src/testing/testing.go:711 +0x2d2
panic(0x5281e0, 0x5fe0c0)
/usr/local/go/src/runtime/panic.go:491 +0x283
github.com/hashicorp/nomad/vendor/github.com/gorhill/cronexpr.(*Expression).nextDayOfMonth(0xc4200c8000, 0xbeb0a5b636ed7f9b, 0x592b5, 0x605ae0, 0x0, 0x0, 0x0)
/home/shanssian/go/src/github.com/hashicorp/nomad/vendor/github.com/gorhill/cronexpr/cronexpr_next.go:118 +0x2be
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.