LogoPly
Middleware

Timeout

Limit handler execution time and return 408 on expiry.

Timeout

middleware.Timeout limits how long the handler chain may run before Ply writes a timeout response.

app.Use(middleware.Timeout(2 * time.Second))

When the deadline is reached, the middleware returns:

HTTP/1.1 408 Request Timeout
Content-Type: text/plain

The body is request timeout.

Behavior

Timeout runs c.Next() in a goroutine and waits for either completion or the timer. On expiry it aborts the chain and writes the 408 response.

Important limitation

The handler goroutine keeps running after the timeout. It is not cancelled. Ply may recycle the request context for another request while the old handler is still executing. Do not touch the context, response, or request data after a timeout.

Use this middleware only when:

  • handlers do not keep writing after the deadline,
  • handlers do not mutate shared state that must be rolled back,
  • the handler is known to finish soon after the response is abandoned.

For work that must be cancelled, pass a timeout-bearing context.Context to database or HTTP clients inside the handler and check it explicitly. Ply does not propagate the middleware timer into the handler.

Example

app.Use(middleware.Timeout(3 * time.Second))

app.Get("/slow", func(c *core.Context) {
	select {
	case <-time.After(5 * time.Second):
		c.Text(200, "finished")
	case <-c.Ctx.Done():
		return
	}
})

c.Ctx.Done() is closed when the client disconnects, not when the middleware timer expires. A handler that blocks without checking it can still outlive the timeout.

Ordering

Place Timeout after recovery and request ID middleware, and before handlers that may block:

app.Use(
	middleware.RequestID(),
	middleware.Recover(),
	middleware.Timeout(2*time.Second),
)