Skip to content

Commit

Permalink
service/scheduler: add Cron type
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatczuk committed Dec 22, 2021
1 parent 0aeedd9 commit 0a30a7c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ issues:
- exported method +\.Close should have comment or be unexported
- exported method .*Value\..+ should have comment or be unexported
- exported method .+\.Init should have comment or be unexported
- exported method .+\.IsZero should have comment or be unexported
- exported method .+\.Key should have comment or be unexported
- exported method .+\.MarshalBinary should have comment or be unexported
- exported method .+\.MarshalCQL should have comment or be unexported
Expand Down
76 changes: 76 additions & 0 deletions pkg/service/scheduler/cron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (C) 2017 ScyllaDB

package scheduler

import (
"time"

"github.com/gocql/gocql"
"github.com/pkg/errors"
"github.com/scylladb/scylla-manager/pkg/scheduler"
"github.com/scylladb/scylla-manager/pkg/scheduler/trigger"
)

// Cron implements a trigger based on cron expression.
// It supports the extended syntax including @monthly, @weekly, @daily, @midnight, @hourly, @every <time.Duration>.
type Cron struct {
spec []byte
inner scheduler.Trigger
}

func NewCron(spec string) (Cron, error) {
t, err := trigger.NewCron(spec)
if err != nil {
return Cron{}, err
}

return Cron{
spec: []byte(spec),
inner: t,
}, nil
}

func NewCronEvery(d time.Duration) Cron {
c, _ := NewCron("@every " + d.String()) // nolint: errcheck
return c
}

// MustCron calls NewCron and panics on error.
func MustCron(spec string) Cron {
c, err := NewCron(spec)
if err != nil {
panic(err)
}
return c
}

// Next implements scheduler.Trigger.
func (c Cron) Next(now time.Time) time.Time {
return c.inner.Next(now)
}

func (c Cron) MarshalText() (text []byte, err error) {
return c.spec, nil
}

func (c *Cron) UnmarshalText(text []byte) error {
v, err := NewCron(string(text))
if err != nil {
return errors.Wrap(err, "cron")
}

*c = v
return nil
}

func (c Cron) MarshalCQL(info gocql.TypeInfo) ([]byte, error) {
return c.MarshalText()
}

func (c *Cron) UnmarshalCQL(info gocql.TypeInfo, data []byte) error {
return c.UnmarshalText(data)
}

func (c Cron) IsZero() bool {
return c.inner == nil
}
28 changes: 28 additions & 0 deletions pkg/service/scheduler/cron_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2021 ScyllaDB

package scheduler

import (
"testing"
"time"
)

func TestCronMarshalUnmarshal(t *testing.T) {
spec := "@every 15s"

var cron Cron
if err := cron.UnmarshalText([]byte(spec)); err != nil {
t.Fatal(err)
}
b, _ := cron.MarshalText()
if string(b) != spec {
t.Fatalf("MarshalText() = %s, expected %s", string(b), spec)
}
}

func TestNewCronEvery(t *testing.T) {
c := NewCronEvery(15 * time.Second)
if c.IsZero() {
t.Fatal()
}
}

0 comments on commit 0a30a7c

Please sign in to comment.