Giter VIP home page Giter VIP logo

cronexpr's People

Contributors

dadgar avatar gorhill avatar safx avatar takumakanari avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cronexpr's Issues

Improve performance where obvious

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.

the DST change on pull 17 cause some new error

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

Support something like RANDOM_DELAY

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.

Could the `expression` field of `Expression` structs be readable somehow?

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.

Wrong calculation on next schedule on cron expression: "*/5 * * * *"

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)

Previous command

I'd love to be able to step backwards to see the previous time a cron has fired.

Day-of-week parse support for MON-SUN (or `1-7`)

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))
			}
		}

	}

}

Add a func to validate whether a cron expression is valid

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.

leading zero are not accepted

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.

Return Error Rather than Panic

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!

Add package comment

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.

Hyphenated hours

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

multi-goroutine map write when init first time

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.

Several parse error

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'

timezone related error on DST on Next()

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

  1. repeat step 2 and infinity loop

Unexported fields in `type Expression`

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.

Why using panic?

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
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.