Skip to content

Commit

Permalink
feat: support NewJobWithNonAnonymousFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfogre committed Mar 3, 2020
1 parent 970e357 commit 825c5d5
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 1 deletion.
33 changes: 32 additions & 1 deletion job.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package dcron

import "context"
import (
"context"
"reflect"
"regexp"
"runtime"
"strings"
)

type JobMeta interface {
Key() string
Expand Down Expand Up @@ -29,6 +35,18 @@ func NewJob(key, spec string, run RunFunc, options ...JobOption) Job {
}
}

// NewJobWithNonAnonymousFunc return a new Job with the 'run' function's name as key.
// Be careful, the 'run' should be a non-anonymous function,
// or returned Job will has a emtpy key, and can not be added to a Cron.
func NewJobWithNonAnonymousFunc(spec string, run RunFunc, options ...JobOption) Job {
return &wrappedJob{
key: funcName(run),
spec: spec,
run: run,
options: options,
}
}

func (j *wrappedJob) Key() string {
return j.key
}
Expand All @@ -47,3 +65,16 @@ func (j *wrappedJob) Run(ctx context.Context) error {
func (j *wrappedJob) Options() []JobOption {
return j.options
}

func funcName(run RunFunc) string {
if run != nil {
name := runtime.FuncForPC(reflect.ValueOf(run).Pointer()).Name()
splits := strings.Split(name, ".")
name = strings.TrimSuffix(splits[len(splits)-1], "-fm") // method closures have a "-fm" suffix
if regexp.MustCompile("^func[0-9]+$").MatchString(name) {
return ""
}
return name
}
return ""
}
77 changes: 77 additions & 0 deletions job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,80 @@ func Test_wrappedJob_Spec(t *testing.T) {
})
}
}

func TestNewJobWithNonAnonymousFunc(t *testing.T) {
type args struct {
spec string
run RunFunc
options []JobOption
}
tests := []struct {
name string
args args
check func(t *testing.T, job Job)
}{
{
name: "regular",
args: args{
run: Func,
},
check: func(t *testing.T, job Job) {
if job.Key() != "Func" {
t.Fatal(job.Key())
}
},
},
{
name: "method",
args: args{
run: Foo{}.Method,
},
check: func(t *testing.T, job Job) {
if job.Key() != "Method" {
t.Fatal(job.Key())
}
},
},
{
name: "nil",
args: args{
run: nil,
},
check: func(t *testing.T, job Job) {
if job.Key() != "" {
t.Fatal(job.Key())
}
},
},
{
name: "anonymous func",
args: args{
run: func(ctx context.Context) error {
return nil
},
},
check: func(t *testing.T, job Job) {
if job.Key() != "" {
t.Fatal(job.Key())
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NewJobWithNonAnonymousFunc(tt.args.spec, tt.args.run, tt.args.options...)
tt.check(t, got)
})
}
}

func Func(ctx context.Context) error {
return nil
}

type Foo struct {
}

func (Foo) Method(ctx context.Context) error {
return nil
}

0 comments on commit 825c5d5

Please sign in to comment.