TimeoutWithCodeHandler creates RequestHandler, which returns an error with the given msg and status code to the client if h didn't return during the given duration. The returned handler may return StatusTooManyRequests error with the given msg to the client if there are more than Server.Concurrenc
(h RequestHandler, timeout time.Duration, msg string, statusCode int)
| 483 | // msg to the client if there are more than Server.Concurrency concurrent |
| 484 | // handlers h are running at the moment. |
| 485 | func TimeoutWithCodeHandler(h RequestHandler, timeout time.Duration, msg string, statusCode int) RequestHandler { |
| 486 | if timeout <= 0 { |
| 487 | return h |
| 488 | } |
| 489 | |
| 490 | return func(ctx *RequestCtx) { |
| 491 | concurrencyCh := ctx.s.concurrencyCh |
| 492 | select { |
| 493 | case concurrencyCh <- struct{}{}: |
| 494 | default: |
| 495 | ctx.Error(msg, StatusTooManyRequests) |
| 496 | return |
| 497 | } |
| 498 | |
| 499 | ch := ctx.timeoutCh |
| 500 | if ch == nil { |
| 501 | ch = make(chan struct{}, 1) |
| 502 | ctx.timeoutCh = ch |
| 503 | } |
| 504 | go func() { |
| 505 | h(ctx) |
| 506 | ch <- struct{}{} |
| 507 | <-concurrencyCh |
| 508 | }() |
| 509 | ctx.timeoutTimer = initTimer(ctx.timeoutTimer, timeout) |
| 510 | select { |
| 511 | case <-ch: |
| 512 | case <-ctx.timeoutTimer.C: |
| 513 | ctx.TimeoutErrorWithCode(msg, statusCode) |
| 514 | } |
| 515 | stopTimer(ctx.timeoutTimer) |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | // RequestConfig configure the per request deadline and body limits. |
| 520 | type RequestConfig struct { |
no test coverage detected
searching dependent graphs…