Merge pull request #132 from syumai/split-wait-for-ready-from-serve

split Done funcs from workers.Serve / cron.ScheduleTask
This commit is contained in:
syumai 2024-11-08 02:40:40 +09:00 committed by GitHub
commit 605532b98b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 168 additions and 16 deletions

View File

@ -1,6 +1,6 @@
.PHONY: dev
dev:
wrangler dev
wrangler dev --test-scheduled
.PHONY: build
build:

View File

@ -18,3 +18,12 @@ make dev # run dev server
make build # build Go Wasm binary
make deploy # deploy worker
```
#### Testing cron schedule
* With curl command below, you can test the cron schedule.
- see: https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/#background
```
curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"
```

View File

@ -3,7 +3,9 @@ package main
import (
"context"
"fmt"
"time"
"github.com/syumai/workers/cloudflare"
"github.com/syumai/workers/cloudflare/cron"
)
@ -15,6 +17,11 @@ func task(ctx context.Context) error {
fmt.Println(e.ScheduledTime.Unix())
cloudflare.WaitUntil(func() {
time.Sleep(1 * time.Second)
fmt.Println("Run sub task after returning from main task")
})
return nil
}

View File

@ -0,0 +1,3 @@
build
node_modules
.wrangler

View File

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

View File

@ -0,0 +1,29 @@
# multiple-handlers
* This example shows how to use multiple handlers in a single worker.
## 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 deploy # deploy worker
```
#### Testing cron schedule
* With curl command below, you can test the cron schedule.
- see: https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/#background
```
curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"
```

View File

@ -0,0 +1,7 @@
module github.com/syumai/workers/_examples/multiple-handlers
go 1.21.3
require github.com/syumai/workers v0.0.0
replace github.com/syumai/workers => ../../

View File

View File

@ -0,0 +1,38 @@
package main
import (
"context"
"fmt"
"net/http"
"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/cron"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, "Hello, world!")
})
task := func(ctx context.Context) error {
e, err := cron.NewEvent(ctx)
if err != nil {
return err
}
fmt.Println(e.ScheduledTime.Unix())
return nil
}
// set up the worker
workers.ServeNonBlock(handler)
cron.ScheduleTaskNonBlock(task)
// send a ready signal to the runtime
workers.Ready()
// block until the handler or task is done
select {
case <-workers.Done():
case <-cron.Done():
}
}

View File

@ -0,0 +1,10 @@
name = "multiple-handlers"
main = "./build/worker.mjs"
compatibility_date = "2023-02-24"
workers_dev = false
[triggers]
crons = ["* * * * *"]
[build]
command = "make build"

View File

@ -5,13 +5,17 @@ import (
"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
var (
scheduledTask Task
doneCh = make(chan struct{})
)
func runScheduler(eventObj js.Value) error {
ctx := runtimecontext.New(context.Background(), eventObj)
@ -46,16 +50,21 @@ 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 {}
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 }
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
}

View File

@ -25,3 +25,15 @@ func Serve(handler http.Handler) {
fmt.Fprintln(os.Stderr, "warn: this server is currently running in non-JS mode. to enable JS-related features, please use the make command in the syumai/workers template.")
http.ListenAndServe(addr, handler)
}
func ServeNonBlock(http.Handler) {
panic("ServeNonBlock is not supported in non-JS environments")
}
func Ready() {
panic("Ready is not supported in non-JS environments")
}
func Done() <-chan struct{} {
panic("Done is not supported in non-JS environments")
}

View File

@ -16,7 +16,7 @@ import (
var (
httpHandler http.Handler
closeCh = make(chan struct{})
doneCh = make(chan struct{})
)
func init() {
@ -52,7 +52,7 @@ type appCloser struct {
}
func (c *appCloser) Close() error {
defer close(closeCh)
defer close(doneCh)
return c.ReadCloser.Close()
}
@ -84,16 +84,32 @@ func handleRequest(reqObj js.Value) (js.Value, error) {
return w.ToJSResponse(), nil
}
//go:wasmimport workers ready
func ready()
// Server serves http.Handler on a JS runtime.
// Serve serves http.Handler on a JS runtime.
// if the given handler is nil, http.DefaultServeMux will be used.
func Serve(handler http.Handler) {
ServeNonBlock(handler)
Ready()
<-Done()
}
// ServeNonBlock sets the http.Handler to be served but does not signal readiness or block
// indefinitely. The non-blocking form is meant to be used in conjunction with Ready and WaitForCompletion.
func ServeNonBlock(handler http.Handler) {
if handler == nil {
handler = http.DefaultServeMux
}
httpHandler = handler
ready()
<-closeCh
}
//go:wasmimport workers ready
func ready()
// Ready must be called after all setups of the Go side's handlers are done.
func Ready() {
ready()
}
// Done returns a channel which is closed when the handler is done.
func Done() <-chan struct{} {
return doneCh
}