2024-11-08 02:33:28 +09:00

71 lines
1.6 KiB
Go

package cron
import (
"context"
"fmt"
"syscall/js"
"github.com/syumai/workers"
"github.com/syumai/workers/internal/jsutil"
"github.com/syumai/workers/internal/runtimecontext"
)
type Task func(ctx context.Context) error
var (
scheduledTask Task
doneCh = make(chan struct{})
)
func runScheduler(eventObj js.Value) error {
ctx := runtimecontext.New(context.Background(), eventObj)
if err := scheduledTask(ctx); err != nil {
return err
}
return nil
}
func init() {
runSchedulerCallback := js.FuncOf(func(_ js.Value, args []js.Value) any {
if len(args) != 1 {
panic(fmt.Errorf("invalid number of arguments given to runScheduler: %d", len(args)))
}
eventObj := args[0]
var cb js.Func
cb = js.FuncOf(func(_ js.Value, pArgs []js.Value) any {
defer cb.Release()
resolve := pArgs[0]
go func() {
err := runScheduler(eventObj)
if err != nil {
panic(err)
}
resolve.Invoke(js.Undefined())
}()
return js.Undefined()
})
return jsutil.NewPromise(cb)
})
jsutil.Binding.Set("runScheduler", runSchedulerCallback)
}
// ScheduleTask sets the Task to be executed
func ScheduleTask(task Task) {
scheduledTask = task
workers.Ready()
<-Done()
}
// ScheduleTaskNonBlock sets the Task to be executed but does not signal readiness or block
// indefinitely. The non-blocking form is meant to be used in conjunction with [workers.Serve].
func ScheduleTaskNonBlock(task Task) {
scheduledTask = task
}
// Done returns a channel which is closed when the task is done.
// Currently, this channel is never closed to support cloudflare.WaitUntil feature.
func Done() <-chan struct{} {
return doneCh
}