github.com/ngicks/gokugen@v0.0.5/example/cron/main.go (about) 1 package main 2 3 import ( 4 "context" 5 _ "embed" 6 "encoding/json" 7 "fmt" 8 "os" 9 "os/signal" 10 "syscall" 11 "time" 12 13 "github.com/ngicks/gokugen" 14 "github.com/ngicks/gokugen/cron" 15 "github.com/ngicks/gokugen/scheduler" 16 ) 17 18 func main() { 19 if err := _main(); err != nil { 20 panic(err) 21 } 22 } 23 24 func printNowWithId(workId string) gokugen.WorkFnWParam { 25 return func(taskCtx context.Context, scheduled time.Time, param any) (any, error) { 26 now := time.Now() 27 var isCtxCancelled bool 28 select { 29 case <-taskCtx.Done(): 30 isCtxCancelled = true 31 default: 32 } 33 34 fmt.Printf( 35 "workId: %s, scheduled: %s, diff to now: %s, isCtxCancelled: %t, param: %v\n", 36 workId, 37 scheduled.Format(time.RFC3339Nano), 38 now.Sub(scheduled).String(), 39 isCtxCancelled, 40 param, 41 ) 42 43 return nil, nil 44 } 45 } 46 47 //go:embed cron_tab.json 48 var tabBin []byte 49 var tab cron.CronTab 50 51 func init() { 52 err := json.Unmarshal(tabBin, &tab) 53 if err != nil { 54 panic(err) 55 } 56 } 57 58 func rowToController( 59 tab []cron.RowLike, 60 whence time.Time, 61 scheduler cron.Scheduler, 62 registry cron.WorkRegistry, 63 ) (reschedulers []*cron.CronLikeRescheduler) { 64 for _, v := range tab { 65 res := cron.NewCronLikeRescheduler( 66 v, 67 whence, 68 func(workErr error, callCount int) bool { return true }, 69 scheduler, 70 registry, 71 ) 72 reschedulers = append(reschedulers, res) 73 } 74 return 75 } 76 77 type PseudoRegistry struct{} 78 79 func (pr PseudoRegistry) Load(key string) (value gokugen.WorkFnWParam, ok bool) { 80 return printNowWithId(key), true 81 } 82 83 func _main() (err error) { 84 now := time.Now() 85 86 sched := gokugen.NewMiddlewareApplicator(scheduler.NewScheduler(5, 0)) 87 88 rows := make([]cron.RowLike, 0) 89 for _, r := range tab { 90 rows = append(rows, r) 91 } 92 rows = append(rows, cron.Duration{Duration: 30 * time.Second, Command: []string{"every_30_seconds"}}) 93 94 reschedulers := rowToController(rows, now, sched, PseudoRegistry{}) 95 96 for _, v := range reschedulers { 97 err = v.Schedule() 98 if err != nil { 99 return 100 } 101 } 102 103 ctx, cancel := context.WithCancel(context.Background()) 104 defer cancel() 105 106 go sched.Scheduler().Start(ctx) 107 108 signalCh := make(chan os.Signal, 1) 109 signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) 110 111 select { 112 case sig := <-signalCh: 113 fmt.Printf("received singal: %s\n", sig) 114 } 115 116 for _, v := range reschedulers { 117 v.Cancel() 118 } 119 cancel() 120 sched.Scheduler().End() 121 122 return 123 }