Merge pull request #45 from aki-0421/scheduled

Add Scheduled worker
This commit is contained in:
syumai 2023-04-30 10:51:30 +09:00 committed by GitHub
commit e1ef423ff7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 167 additions and 1 deletions

View File

@ -22,3 +22,8 @@ export async function fetch(req, env, ctx) {
await run();
return handleRequest(req, { env, ctx });
}
export async function scheduled(event, env, ctx) {
await run();
return runScheduler(event, { env, ctx });
}

View File

@ -3,4 +3,4 @@ import mod from "./app.wasm";
imports.init(mod);
export default { fetch: imports.fetch }
export default { fetch: imports.fetch, scheduled: imports.scheduled }

84
cron.go Normal file
View File

@ -0,0 +1,84 @@
package workers
import (
"context"
"errors"
"fmt"
"syscall/js"
"time"
"github.com/syumai/workers/internal/jsutil"
"github.com/syumai/workers/internal/runtimecontext"
)
// CronEvent represents information about the Cron that invoked this worker.
type CronEvent struct {
// Type string
Cron string
ScheduledTime time.Time
}
// toGo converts JS Object to CronEvent
func (ce *CronEvent) toGo(obj js.Value) error {
if obj.IsUndefined() {
return errors.New("event is null")
}
cronVal := obj.Get("cron").String()
ce.Cron = cronVal
scheduledTimeVal := obj.Get("scheduledTime").Float()
ce.ScheduledTime = time.Unix(int64(scheduledTimeVal)/1000, 0).UTC()
return nil
}
type CronFunc func(ctx context.Context, event CronEvent) error
var cronTask CronFunc
// ScheduleTask sets the CronFunc to be executed
func ScheduleTask(task CronFunc) {
cronTask = task
jsutil.Global.Call("ready")
select {}
}
func runScheduler(eventObj js.Value, runtimeCtxObj js.Value) error {
ctx := runtimecontext.New(context.Background(), runtimeCtxObj)
event := CronEvent{}
err := event.toGo(eventObj)
if err != nil {
return err
}
err = cronTask(ctx, event)
if err != nil {
return err
}
return nil
}
func init() {
runSchedulerCallback := js.FuncOf(func(_ js.Value, args []js.Value) any {
if len(args) != 2 {
panic(fmt.Errorf("invalid number of arguments given to runScheduler: %d", len(args)))
}
event := args[0]
runtimeCtx := args[1]
var cb js.Func
cb = js.FuncOf(func(_ js.Value, pArgs []js.Value) any {
defer cb.Release()
resolve := pArgs[0]
go func() {
err := runScheduler(event, runtimeCtx)
if err != nil {
panic(err)
}
resolve.Invoke(js.Undefined())
}()
return js.Undefined()
})
return jsutil.NewPromise(cb)
})
jsutil.Global.Set("runScheduler", runSchedulerCallback)
}

1
examples/cron/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

12
examples/cron/Makefile Normal file
View File

@ -0,0 +1,12 @@
.PHONY: dev
dev:
wrangler dev
.PHONY: build
build:
go run ../../cmd/workers-assets-gen
tinygo build -o ./build/app.wasm -target wasm ./...
.PHONY: publish
publish:
wrangler publish

20
examples/cron/README.md Normal file
View File

@ -0,0 +1,20 @@
# [Cron](https://developers.cloudflare.com/workers/platform/triggers/cron-triggers/)
* Create a worker to be triggered by Cron.
## Development
### Requirements
This project requires these tools to be installed globally.
* wrangler
* tinygo
### Commands
```
make dev # run dev server
make build # build Go Wasm binary
make publish # publish worker
```

7
examples/cron/go.mod Normal file
View File

@ -0,0 +1,7 @@
module github.com/syumai/workers/examples/scheduled
go 1.18
require github.com/syumai/workers v0.0.0
replace github.com/syumai/workers => ../../

0
examples/cron/go.sum Normal file
View File

24
examples/cron/main.go Normal file
View File

@ -0,0 +1,24 @@
package main
import (
"context"
"errors"
"fmt"
"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare"
)
func task(ctx context.Context, event workers.CronEvent) error {
fmt.Println(cloudflare.Getenv(ctx, "HELLO"))
if event.ScheduledTime.Minute()%2 == 0 {
return errors.New("even numbers cause errors")
}
return nil
}
func main() {
workers.ScheduleTask(task)
}

View File

@ -0,0 +1,13 @@
name = "scheduled"
main = "./build/worker.mjs"
compatibility_date = "2023-02-24"
workers_dev = false
[vars]
HELLO = "hello, world!"
[triggers]
crons = ["* * * * *"]
[build]
command = "make build"