middleware/timeout: implement timeout middleware

This commit is contained in:
Muyao CHEN 2024-09-24 23:21:48 +02:00
parent 14af16c71e
commit e8c4cbaa89
2 changed files with 44 additions and 1 deletions

View File

@ -97,6 +97,12 @@ func (ctx *Context) Value(key any) any {
return ctx.BaseContext().Value(key) return ctx.BaseContext().Value(key)
} }
// Next runs the next function in the function chain
func (ctx *Context) Next() error {
// TODO
return nil
}
// }}} // }}}
// {{{ Implements request functions // {{{ Implements request functions

View File

@ -1,11 +1,48 @@
package middleware package middleware
import ( import (
"context"
"log"
"net/http"
"time" "time"
"git.vinchent.xyz/vinchent/go-web/framework" "git.vinchent.xyz/vinchent/go-web/framework"
) )
func Timeout(d time.Duration) framework.ControllerHandler { func Timeout(d time.Duration) framework.ControllerHandler {
return func(c *framework.Context) error { return nil } return func(c *framework.Context) error {
finish := make(chan struct{}, 1)
panicChan := make(chan interface{}, 1)
durationCtx, cancel := context.WithTimeout(c.BaseContext(), d)
defer cancel()
go func() {
// Handle panic
defer func() {
if p := recover(); p != nil {
panicChan <- p
}
}()
// Run the next middleware or the business logic
c.Next()
finish <- struct{}{}
}()
select {
case p := <-panicChan:
// panic
log.Println(p)
c.GetResponseWriter().WriteHeader(http.StatusInternalServerError)
case <-finish:
// finish normally
log.Println("finish")
case <-durationCtx.Done():
c.SetHasTimeout()
c.GetResponseWriter().Write([]byte("time out"))
}
return nil
}
} }