feat: release v0.27 unified HTTP limits and safe request shutdown
This commit is contained in:
62
examples/httpSafety/main.go
Normal file
62
examples/httpSafety/main.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// This example uses only local HTTP and simulated work; no external services.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
omni "git.yuntuo.hk/k2safe/go-omni"
|
||||
"git.yuntuo.hk/k2safe/go-omni/lifecycle"
|
||||
)
|
||||
|
||||
func main() {
|
||||
address := flag.String("addr", "127.0.0.1:8080", "local listen address")
|
||||
flag.Parse()
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
if err := run(ctx, *address); err != nil {
|
||||
log.Print(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(ctx context.Context, address string) (runErr error) {
|
||||
deps := lifecycle.NewRuntime(ctx)
|
||||
deps.OnClose(func() error { log.Print("shared resource closed after requests completed"); return nil })
|
||||
defer func() { runErr = deps.Finish(runErr) }()
|
||||
app := omni.New(omni.WithHTTPConfig(omni.HTTPConfig{
|
||||
DefaultMaxBodyBytes: 1 << 20,
|
||||
MaxBodyBytes: 20 << 20,
|
||||
ShutdownCancelTimeout: time.Second,
|
||||
}), omni.WithShutdownTimeout(time.Second))
|
||||
defer func() { runErr = errors.Join(runErr, app.Close()) }()
|
||||
app.HandleWithBodyLimit("POST", "/upload", 16<<20, nil, func(c *omni.Context) error {
|
||||
n, err := io.Copy(io.Discard, c.Request().Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.OK(map[string]int64{"bytes": n})
|
||||
})
|
||||
app.GET("/work", func(c *omni.Context) error {
|
||||
log.Print("request accepted")
|
||||
select {
|
||||
case <-time.After(10 * time.Second):
|
||||
return c.OK("finished")
|
||||
case <-c.Context().Done():
|
||||
// Simulate bounded rollback/cleanup after cancellation. Dependencies
|
||||
// remain available until this handler and its defers have returned.
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
log.Print("request cleanup completed")
|
||||
return c.Context().Err()
|
||||
}
|
||||
})
|
||||
log.Printf("listening on %s; POST /upload or GET /work, then Ctrl-C", address)
|
||||
return app.RunContext(deps.Context(), address)
|
||||
}
|
||||
Reference in New Issue
Block a user