timer.go 850 B

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. package router
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "github.com/imgproxy/imgproxy/v3/ierrors"
  8. "github.com/imgproxy/imgproxy/v3/metrics"
  9. )
  10. type timerSinceCtxKey = struct{}
  11. func setRequestTime(r *http.Request) *http.Request {
  12. return r.WithContext(
  13. context.WithValue(r.Context(), timerSinceCtxKey{}, time.Now()),
  14. )
  15. }
  16. func ctxTime(ctx context.Context) time.Duration {
  17. if t, ok := ctx.Value(timerSinceCtxKey{}).(time.Time); ok {
  18. return time.Since(t)
  19. }
  20. return 0
  21. }
  22. func CheckTimeout(ctx context.Context) {
  23. select {
  24. case <-ctx.Done():
  25. d := ctxTime(ctx)
  26. if ctx.Err() != context.DeadlineExceeded {
  27. panic(ierrors.New(499, fmt.Sprintf("Request was cancelled after %v", d), "Cancelled"))
  28. }
  29. metrics.SendTimeout(ctx, d)
  30. panic(ierrors.New(503, fmt.Sprintf("Timeout after %v", d), "Timeout"))
  31. default:
  32. // Go ahead
  33. }
  34. }