Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Incoming Properties #88

Merged
merged 13 commits into from
Jan 24, 2024
13 changes: 6 additions & 7 deletions _examples/cron/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ package main

import (
"context"
"errors"
"fmt"

"github.com/syumai/workers/cloudflare"
"github.com/syumai/workers/cloudflare/cron"
)

func task(ctx context.Context, event *cron.Event) error {
fmt.Println(cloudflare.Getenv(ctx, "HELLO"))

if event.ScheduledTime.Minute()%2 == 0 {
return errors.New("even numbers cause errors")
func task(ctx context.Context) error {
e, err := cron.NewEvent(ctx)
if err != nil {
return err
}

fmt.Println(e.ScheduledTime.Unix())

return nil
}

Expand Down
3 changes: 0 additions & 3 deletions _examples/cron/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ main = "./build/worker.mjs"
compatibility_date = "2023-02-24"
workers_dev = false

[vars]
HELLO = "hello, world!"

[triggers]
crons = ["* * * * *"]

Expand Down
3 changes: 3 additions & 0 deletions _examples/incoming/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
node_modules
.wrangler
12 changes: 12 additions & 0 deletions _examples/incoming/Makefile
Original file line number Diff line number Diff line change
@@ -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 -no-debug ./...

.PHONY: deploy
deploy:
wrangler deploy
7 changes: 7 additions & 0 deletions _examples/incoming/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/syumai/workers/_examples/incoming

go 1.21.3

require github.com/syumai/workers v0.0.0

replace github.com/syumai/workers => ../../
2 changes: 2 additions & 0 deletions _examples/incoming/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/syumai/workers v0.1.0 h1:z5QfQR2X+PCKzom7RodpI5J4D5YF7NT7Qwzb9AM9dgY=
github.com/syumai/workers v0.1.0/go.mod h1:alXIDhTyeTwSzh0ZgQ3cb9HQPyyYfIejupE4Z3efr14=
27 changes: 27 additions & 0 deletions _examples/incoming/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"encoding/json"
"net/http"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/fetch"
)

func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
p, err := fetch.NewIncomingProperties(req.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

encoder := json.NewEncoder(w)
w.Header().Set("Content-Type", "application/json")
if err := encoder.Encode(p); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
workers.Serve(handler)
}
9 changes: 9 additions & 0 deletions _examples/incoming/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "incoming"
main = "./build/worker.mjs"
compatibility_date = "2022-05-13"
compatibility_flags = [
"streams_enable_constructors"
]

[build]
command = "make build"
28 changes: 28 additions & 0 deletions cloudflare/cron/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cron

import (
"context"
"errors"
"time"

"github.com/syumai/workers/internal/runtimecontext"
)

// Event represents information about the Cron that invoked this worker.
type Event struct {
Cron string
ScheduledTime time.Time
}

func NewEvent(ctx context.Context) (*Event, error) {
obj := runtimecontext.MustExtractTriggerObj(ctx)
if obj.IsUndefined() {
return nil, errors.New("event is null")
}

scheduledTimeVal := obj.Get("scheduledTime").Float()
return &Event{
Cron: obj.Get("cron").String(),
ScheduledTime: time.Unix(int64(scheduledTimeVal)/1000, 0).UTC(),
}, nil
}
58 changes: 17 additions & 41 deletions cloudflare/cron/cron.go → cloudflare/cron/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,38 @@ package cron

import (
"context"
"errors"
"fmt"
"syscall/js"
"time"

"github.com/syumai/workers/internal/jsutil"
"github.com/syumai/workers/internal/runtimecontext"
)

// Event represents information about the Cron that invoked this worker.
type Event struct {
Cron string
ScheduledTime time.Time
}

// toEvent converts JS Object to Go Event struct
func toEvent(obj js.Value) (*Event, error) {
if obj.IsUndefined() {
return nil, errors.New("event is null")
}
cronVal := obj.Get("cron").String()
scheduledTimeVal := obj.Get("scheduledTime").Float()
return &Event{
Cron: cronVal,
ScheduledTime: time.Unix(int64(scheduledTimeVal)/1000, 0).UTC(),
}, nil
}

type Task func(ctx context.Context, event *Event) error
type Task func(ctx context.Context) error

var scheduledTask Task

// ScheduleTask sets the Task to be executed
func ScheduleTask(task Task) {
scheduledTask = task
js.Global().Call("ready")
select {}
}

func runScheduler(eventObj js.Value, runtimeCtxObj js.Value) error {
ctx := runtimecontext.New(context.Background(), runtimeCtxObj)
event, err := toEvent(eventObj)
if err != nil {
return err
}
err = scheduledTask(ctx, event)
if err != nil {
ctx := runtimecontext.New(context.Background(), eventObj, runtimeCtxObj)
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) != 2 {
if len(args) != 1 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to fix this. Thanks!

panic(fmt.Errorf("invalid number of arguments given to runScheduler: %d", len(args)))
}
event := args[0]
runtimeCtx := args[1]

eventObj := args[0]
runtimeCtxObj := jsutil.RuntimeContext
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)
err := runScheduler(eventObj, runtimeCtxObj)
if err != nil {
panic(err)
}
Expand All @@ -80,3 +46,13 @@ func init() {
})
jsutil.Binding.Set("runScheduler", runSchedulerCallback)
}

//go:wasmimport workers ready
func ready()

// ScheduleTask sets the Task to be executed
func ScheduleTask(task Task) {
scheduledTask = task
ready()
select {}
}
5 changes: 4 additions & 1 deletion cloudflare/fetch/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ func fetch(namespace js.Value, req *http.Request, init *RequestInit) (*http.Resp
if namespace.IsUndefined() {
return nil, errors.New("fetch function not found")
}
promise := namespace.Call("fetch",
fetchObj := namespace.Get("fetch")
promise := fetchObj.Invoke(
// The Request object to fetch.
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request
jshttp.ToJSRequest(req),
// The content of the request.
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request#requestinit
init.ToJS(),
)

jsRes, err := jsutil.AwaitPromise(promise)
if err != nil {
return nil, err
}

return jshttp.ToResponse(jsRes)
}
Loading
Loading