Merge pull request #30 from dadgar/b-concurrent
Allow library to be used in parallel
This commit is contained in:
		
						commit
						88b0669f7d
					
				| 
						 | 
					@ -19,6 +19,7 @@ import (
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
| 
						 | 
					@ -194,6 +195,7 @@ var (
 | 
				
			||||||
	fieldFinder               = regexp.MustCompile(`\S+`)
 | 
						fieldFinder               = regexp.MustCompile(`\S+`)
 | 
				
			||||||
	entryFinder               = regexp.MustCompile(`[^,]+`)
 | 
						entryFinder               = regexp.MustCompile(`[^,]+`)
 | 
				
			||||||
	layoutRegexp              = make(map[string]*regexp.Regexp)
 | 
						layoutRegexp              = make(map[string]*regexp.Regexp)
 | 
				
			||||||
 | 
						layoutRegexpLock          sync.Mutex
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
| 
						 | 
					@ -488,6 +490,9 @@ func genericFieldParse(s string, desc fieldDescriptor) ([]*cronDirective, error)
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeLayoutRegexp(layout, value string) *regexp.Regexp {
 | 
					func makeLayoutRegexp(layout, value string) *regexp.Regexp {
 | 
				
			||||||
 | 
						layoutRegexpLock.Lock()
 | 
				
			||||||
 | 
						defer layoutRegexpLock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	layout = strings.Replace(layout, `%value%`, value, -1)
 | 
						layout = strings.Replace(layout, `%value%`, value, -1)
 | 
				
			||||||
	re := layoutRegexp[layout]
 | 
						re := layoutRegexp[layout]
 | 
				
			||||||
	if re == nil {
 | 
						if re == nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,15 +10,13 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package cronexpr_test
 | 
					package cronexpr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/gorhill/cronexpr"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
| 
						 | 
					@ -203,9 +201,9 @@ func TestExpressions(t *testing.T) {
 | 
				
			||||||
	for _, test := range crontests {
 | 
						for _, test := range crontests {
 | 
				
			||||||
		for _, times := range test.times {
 | 
							for _, times := range test.times {
 | 
				
			||||||
			from, _ := time.Parse("2006-01-02 15:04:05", times.from)
 | 
								from, _ := time.Parse("2006-01-02 15:04:05", times.from)
 | 
				
			||||||
			expr, err := cronexpr.Parse(test.expr)
 | 
								expr, err := Parse(test.expr)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Errorf(`cronexpr.Parse("%s") returned "%s"`, test.expr, err.Error())
 | 
									t.Errorf(`Parse("%s") returned "%s"`, test.expr, err.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			next := expr.Next(from)
 | 
								next := expr.Next(from)
 | 
				
			||||||
			nextstr := next.Format(test.layout)
 | 
								nextstr := next.Format(test.layout)
 | 
				
			||||||
| 
						 | 
					@ -220,17 +218,17 @@ func TestExpressions(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestZero(t *testing.T) {
 | 
					func TestZero(t *testing.T) {
 | 
				
			||||||
	from, _ := time.Parse("2006-01-02", "2013-08-31")
 | 
						from, _ := time.Parse("2006-01-02", "2013-08-31")
 | 
				
			||||||
	next := cronexpr.MustParse("* * * * * 1980").Next(from)
 | 
						next := MustParse("* * * * * 1980").Next(from)
 | 
				
			||||||
	if next.IsZero() == false {
 | 
						if next.IsZero() == false {
 | 
				
			||||||
		t.Error(`("* * * * * 1980").Next("2013-08-31").IsZero() returned 'false', expected 'true'`)
 | 
							t.Error(`("* * * * * 1980").Next("2013-08-31").IsZero() returned 'false', expected 'true'`)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	next = cronexpr.MustParse("* * * * * 2050").Next(from)
 | 
						next = MustParse("* * * * * 2050").Next(from)
 | 
				
			||||||
	if next.IsZero() == true {
 | 
						if next.IsZero() == true {
 | 
				
			||||||
		t.Error(`("* * * * * 2050").Next("2013-08-31").IsZero() returned 'true', expected 'false'`)
 | 
							t.Error(`("* * * * * 2050").Next("2013-08-31").IsZero() returned 'true', expected 'false'`)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	next = cronexpr.MustParse("* * * * * 2099").Next(time.Time{})
 | 
						next = MustParse("* * * * * 2099").Next(time.Time{})
 | 
				
			||||||
	if next.IsZero() == false {
 | 
						if next.IsZero() == false {
 | 
				
			||||||
		t.Error(`("* * * * * 2014").Next(time.Time{}).IsZero() returned 'true', expected 'false'`)
 | 
							t.Error(`("* * * * * 2014").Next(time.Time{}).IsZero() returned 'true', expected 'false'`)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -247,7 +245,7 @@ func TestNextN(t *testing.T) {
 | 
				
			||||||
		"Sat, 29 Nov 2014 00:00:00",
 | 
							"Sat, 29 Nov 2014 00:00:00",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	from, _ := time.Parse("2006-01-02 15:04:05", "2013-09-02 08:44:30")
 | 
						from, _ := time.Parse("2006-01-02 15:04:05", "2013-09-02 08:44:30")
 | 
				
			||||||
	result := cronexpr.MustParse("0 0 * * 6#5").NextN(from, uint(len(expected)))
 | 
						result := MustParse("0 0 * * 6#5").NextN(from, uint(len(expected)))
 | 
				
			||||||
	if len(result) != len(expected) {
 | 
						if len(result) != len(expected) {
 | 
				
			||||||
		t.Errorf(`MustParse("0 0 * * 6#5").NextN("2013-09-02 08:44:30", 5):\n"`)
 | 
							t.Errorf(`MustParse("0 0 * * 6#5").NextN("2013-09-02 08:44:30", 5):\n"`)
 | 
				
			||||||
		t.Errorf(`  Expected %d returned time values but got %d instead`, len(expected), len(result))
 | 
							t.Errorf(`  Expected %d returned time values but got %d instead`, len(expected), len(result))
 | 
				
			||||||
| 
						 | 
					@ -270,7 +268,7 @@ func TestNextN_every5min(t *testing.T) {
 | 
				
			||||||
		"Mon, 2 Sep 2013 09:05:00",
 | 
							"Mon, 2 Sep 2013 09:05:00",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	from, _ := time.Parse("2006-01-02 15:04:05", "2013-09-02 08:44:32")
 | 
						from, _ := time.Parse("2006-01-02 15:04:05", "2013-09-02 08:44:32")
 | 
				
			||||||
	result := cronexpr.MustParse("*/5 * * * *").NextN(from, uint(len(expected)))
 | 
						result := MustParse("*/5 * * * *").NextN(from, uint(len(expected)))
 | 
				
			||||||
	if len(result) != len(expected) {
 | 
						if len(result) != len(expected) {
 | 
				
			||||||
		t.Errorf(`MustParse("*/5 * * * *").NextN("2013-09-02 08:44:30", 5):\n"`)
 | 
							t.Errorf(`MustParse("*/5 * * * *").NextN("2013-09-02 08:44:30", 5):\n"`)
 | 
				
			||||||
		t.Errorf(`  Expected %d returned time values but got %d instead`, len(expected), len(result))
 | 
							t.Errorf(`  Expected %d returned time values but got %d instead`, len(expected), len(result))
 | 
				
			||||||
| 
						 | 
					@ -286,22 +284,22 @@ func TestNextN_every5min(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Issue: https://github.com/gorhill/cronexpr/issues/16
 | 
					// Issue: https://github.com/gorhill/cronexpr/issues/16
 | 
				
			||||||
func TestInterval_Interval60Issue(t *testing.T) {
 | 
					func TestInterval_Interval60Issue(t *testing.T) {
 | 
				
			||||||
	_, err := cronexpr.Parse("*/60 * * * * *")
 | 
						_, err := Parse("*/60 * * * * *")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		t.Errorf("parsing with interval 60 should return err")
 | 
							t.Errorf("parsing with interval 60 should return err")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = cronexpr.Parse("*/61 * * * * *")
 | 
						_, err = Parse("*/61 * * * * *")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		t.Errorf("parsing with interval 61 should return err")
 | 
							t.Errorf("parsing with interval 61 should return err")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = cronexpr.Parse("2/60 * * * * *")
 | 
						_, err = Parse("2/60 * * * * *")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		t.Errorf("parsing with interval 60 should return err")
 | 
							t.Errorf("parsing with interval 60 should return err")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = cronexpr.Parse("2-20/61 * * * * *")
 | 
						_, err = Parse("2-20/61 * * * * *")
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		t.Errorf("parsing with interval 60 should return err")
 | 
							t.Errorf("parsing with interval 60 should return err")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -322,14 +320,14 @@ var benchmarkExpressionsLen = len(benchmarkExpressions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkParse(b *testing.B) {
 | 
					func BenchmarkParse(b *testing.B) {
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		_ = cronexpr.MustParse(benchmarkExpressions[i%benchmarkExpressionsLen])
 | 
							_ = MustParse(benchmarkExpressions[i%benchmarkExpressionsLen])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkNext(b *testing.B) {
 | 
					func BenchmarkNext(b *testing.B) {
 | 
				
			||||||
	exprs := make([]*cronexpr.Expression, benchmarkExpressionsLen)
 | 
						exprs := make([]*Expression, benchmarkExpressionsLen)
 | 
				
			||||||
	for i := 0; i < benchmarkExpressionsLen; i++ {
 | 
						for i := 0; i < benchmarkExpressionsLen; i++ {
 | 
				
			||||||
		exprs[i] = cronexpr.MustParse(benchmarkExpressions[i])
 | 
							exprs[i] = MustParse(benchmarkExpressions[i])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	from := time.Now()
 | 
						from := time.Now()
 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,15 +8,13 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package cronexpr_test
 | 
					package cronexpr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/gorhill/cronexpr"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/******************************************************************************/
 | 
					/******************************************************************************/
 | 
				
			||||||
| 
						 | 
					@ -24,7 +22,7 @@ import (
 | 
				
			||||||
// ExampleMustParse
 | 
					// ExampleMustParse
 | 
				
			||||||
func ExampleMustParse() {
 | 
					func ExampleMustParse() {
 | 
				
			||||||
	t := time.Date(2013, time.August, 31, 0, 0, 0, 0, time.UTC)
 | 
						t := time.Date(2013, time.August, 31, 0, 0, 0, 0, time.UTC)
 | 
				
			||||||
	nextTimes := cronexpr.MustParse("0 0 29 2 *").NextN(t, 5)
 | 
						nextTimes := MustParse("0 0 29 2 *").NextN(t, 5)
 | 
				
			||||||
	for i := range nextTimes {
 | 
						for i := range nextTimes {
 | 
				
			||||||
		fmt.Println(nextTimes[i].Format(time.RFC1123))
 | 
							fmt.Println(nextTimes[i].Format(time.RFC1123))
 | 
				
			||||||
		// Output:
 | 
							// Output:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue