iris icon indicating copy to clipboard operation
iris copied to clipboard

TimeoutHandler

Open sado0823 opened this issue 3 years ago • 8 comments

@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

sado0823 avatar Apr 07 '21 15:04 sado0823

@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)

sado0823 avatar Apr 07 '21 15:04 sado0823

Hello @sado0823 , The iris.FromStd doesn't work here?

app.Use(iris.FromStd(TimeoutHandler(10 * time.Second))) // or app.UseRouter(...).

kataras avatar Apr 13 '21 18:04 kataras

right image

i can't find another way to use this original handler http.TimeoutHandler(next, duration, reason)

sado0823 avatar Apr 14 '21 01:04 sado0823

@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 avatar Apr 28 '21 08:04 tuhao1020

@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 avatar Apr 28 '21 09:04 sado0823

@sado0823 looks nice!

tuhao1020 avatar Apr 28 '21 09:04 tuhao1020

try it, looking forward to your feedback :)

sado0823 avatar Apr 28 '21 09:04 sado0823

@sado0823 your code can't stopped the current running handler too 😞

@kataras it seems no way to stop it, right?

tuhao1020 avatar Apr 28 '21 10:04 tuhao1020