Context: Test context with timeout

This commit is contained in:
Muyao CHEN 2024-09-15 22:39:58 +02:00
parent f076ebaa3a
commit 913e33a993
3 changed files with 68 additions and 9 deletions

58
handlers.go Normal file
View File

@ -0,0 +1,58 @@
package main
import (
"context"
"log"
"net/http"
"time"
"git.vinchent.xyz/vinchent/go-web/framework"
)
// func FooControllerHandler(ctx *framework.Context) error {
// return ctx.WriteJSON(http.StatusOK, map[string]any{
// "code": 0,
// })
// }
func FooControllerHandler(ctx *framework.Context) error {
durationCtx, cancel := context.WithTimeout(ctx.BaseContext(), time.Duration(1*time.Second))
defer cancel()
finish := make(chan struct{}, 1)
panicChan := make(chan interface{}, 1)
// some long task
go func() {
// Deal with the panic during the work
defer func() {
if p := recover(); p != nil {
panicChan <- p
}
}()
// do the business
time.Sleep(10 * time.Second)
ctx.WriteJSON(http.StatusOK, "ok")
finish <- struct{}{}
}()
select {
case <-panicChan:
// Protect ResponseWriter for concurrently writing from different
// goroutines if there are any
ctx.WriterMux().Lock()
defer ctx.WriterMux().Unlock()
log.Println("panicked")
ctx.WriteJSON(http.StatusInternalServerError, "panicked")
case <-finish:
log.Println("finished")
case <-durationCtx.Done():
ctx.WriterMux().Lock()
defer ctx.WriterMux().Unlock()
log.Println("Timeout")
ctx.WriteJSON(http.StatusInternalServerError, "time out")
ctx.SetHasTimeout()
}
return nil
}

12
main.go
View File

@ -1,24 +1,18 @@
package main
import (
"fmt"
"html"
"log"
"net/http"
"git.vinchent.xyz/vinchent/go-web/framework"
)
type FooHandler struct{}
func (foo FooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}
func main() {
core := framework.NewCore()
registerRouter(core)
server := &http.Server{
Addr: ":8080",
Handler: framework.NewCore(),
Handler: core,
}
if err := server.ListenAndServe(); err != nil {

7
routes.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "git.vinchent.xyz/vinchent/go-web/framework"
func registerRouter(core *framework.Core) {
core.Get("foo", FooControllerHandler)
}