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  }