1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-12-23 22:11:10 +02:00
Files
imgproxy/server/timer.go

52 lines
1.3 KiB
Go
Raw Permalink Normal View History

// timer.go contains methods for storing, retrieving and checking
// timer in a request context.
package server
2021-04-26 17:52:50 +06:00
import (
"context"
"net/http"
"time"
2021-09-30 20:23:30 +06:00
"github.com/imgproxy/imgproxy/v3/ierrors"
2021-04-26 17:52:50 +06:00
)
// timerSinceCtxKey represents a context key for start time.
2024-10-02 23:43:24 +03:00
type timerSinceCtxKey struct{}
2021-04-26 17:52:50 +06:00
// startRequestTimer starts a new request timer.
2025-09-30 13:24:23 +02:00
func startRequestTimer(r *http.Request, timeout time.Duration) (*http.Request, context.CancelFunc) {
2022-01-14 00:18:48 +06:00
ctx := r.Context()
ctx = context.WithValue(ctx, timerSinceCtxKey{}, time.Now())
2025-09-30 13:24:23 +02:00
ctx, cancel := context.WithTimeout(ctx, timeout)
2022-01-14 00:18:48 +06:00
return r.WithContext(ctx), cancel
2021-04-26 17:52:50 +06:00
}
// requestStartedAt returns the duration since the timer started in the context.
func requestStartedAt(ctx context.Context) time.Duration {
2021-04-26 17:52:50 +06:00
if t, ok := ctx.Value(timerSinceCtxKey{}).(time.Time); ok {
return time.Since(t)
}
return 0
}
// CheckTimeout checks if the request context has timed out or cancelled and returns
// wrapped error.
2022-07-20 15:49:05 +06:00
func CheckTimeout(ctx context.Context) error {
2021-04-26 17:52:50 +06:00
select {
case <-ctx.Done():
d := requestStartedAt(ctx)
2021-04-26 17:52:50 +06:00
2022-07-19 18:10:18 +06:00
err := ctx.Err()
switch err {
case context.Canceled:
return newRequestCancelledError(d)
2022-07-19 18:10:18 +06:00
case context.DeadlineExceeded:
return newRequestTimeoutError(d)
2022-07-19 18:10:18 +06:00
default:
return ierrors.Wrap(err, 0, ierrors.WithCategory(categoryTimeout))
2021-04-26 17:52:50 +06:00
}
default:
2022-07-20 15:49:05 +06:00
return nil
2021-04-26 17:52:50 +06:00
}
}