mirror of
https://github.com/syumai/workers.git
synced 2025-03-10 17:29:11 +00:00
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:
commit
605532b98b
@ -1,6 +1,6 @@
|
||||
.PHONY: dev
|
||||
dev:
|
||||
wrangler dev
|
||||
wrangler dev --test-scheduled
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
|
@ -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=*+*+*+*+*"
|
||||
```
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
3
_examples/multiple-handlers/.gitignore
vendored
Normal file
3
_examples/multiple-handlers/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
build
|
||||
node_modules
|
||||
.wrangler
|
12
_examples/multiple-handlers/Makefile
Normal file
12
_examples/multiple-handlers/Makefile
Normal 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
|
29
_examples/multiple-handlers/README.md
Normal file
29
_examples/multiple-handlers/README.md
Normal 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=*+*+*+*+*"
|
||||
```
|
7
_examples/multiple-handlers/go.mod
Normal file
7
_examples/multiple-handlers/go.mod
Normal 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 => ../../
|
0
_examples/multiple-handlers/go.sum
Normal file
0
_examples/multiple-handlers/go.sum
Normal file
38
_examples/multiple-handlers/main.go
Normal file
38
_examples/multiple-handlers/main.go
Normal 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():
|
||||
}
|
||||
}
|
10
_examples/multiple-handlers/wrangler.toml
Normal file
10
_examples/multiple-handlers/wrangler.toml
Normal 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"
|
@ -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
|
||||
}
|
||||
|
12
handler.go
12
handler.go
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user