iris
iris copied to clipboard
TimeoutHandler
@kataras hi, is there a way to do in iris
like this in net/http
?
func TimeoutHandler(duration time.Duration) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
if duration > 0 {
return http.TimeoutHandler(next, duration, reason)
}
return next
}
}
i want to set a http timeout, and get `503` code
Originally posted by @sado0823 in https://github.com/kataras/iris/issues/1668#issuecomment-814874372
@kataras in this way , when timeout , i can not get any response and header
srv := &http.Server{
Addr: ":8080",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
app.Run(iris.Server(srv))
Error: Server returned nothing (no headers, no data)
Hello @sado0823 , The iris.FromStd
doesn't work here?
app.Use(iris.FromStd(TimeoutHandler(10 * time.Second))) // or app.UseRouter(...).
right
i can't find another way to use this original handler http.TimeoutHandler(next, duration, reason)
@sado0823
func TimeoutHandler(duration time.Duration) iris.Handler {
return func(ctx iris.Context) {
if duration <= 0 {
ctx.Next()
return
}
t := time.After(duration)
go ctx.Next()
<-t
if !ctx.IsStopped() {
ctx.StatusCode(iris.StatusGatewayTimeout)
ctx.StopExecution()
}
}
}
@tuhao1020
in this way, even timeout, the goroutine go ctx.Next()
would not stop
now i try the follow way to handle timeout
ctx,_ := context.withTimeout(.....)
c.ResetRequest(c.Request().WithContext(ctx))
done := make(chan struct{})
clone := c.ResponseWriter().Clone()
c.Next()
go func() { done <- struct{} }()
select {
case <-ctx.Done():
c.ResetResponseWriter(clone)
c.StatusCode(http.StatusGatewayTimeout)
c.StopWithError(http.StatusGatewayTimeout, errors.New(contextTimeoutReason))
return
case <-done:
return
}
@sado0823 looks nice!
try it, looking forward to your feedback :)
@sado0823 your code can't stopped the current running handler too 😞
@kataras it seems no way to stop it, right?