-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add context timeout middleware #2380
Conversation
Add context timeout middleware Co-authored-by: Erhan Akpınar <erhan.akpinar@yemeksepeti.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this error handling part is too rigid. It should be left to developer to decide.
Also err = c.Request().Context().Err()
should not be needed as then context timeouts your timeout aware methods should return that error. unless you are warpping somewhere you should not need to check it from request.
and middlewares should not handle errors like that return c.JSON(http.StatusServiceUnavailable, suResponse)
this means that now your middleware "commits" that response and midlewares up in stack can not handle errors anymore
I propose something like that instead:
type ContextTimeoutConfig struct {
Skipper middleware.Skipper
ErrorHandler func(err error, c echo.Context) error
Timeout time.Duration
}
func ContextTimeout(timeout time.Duration) echo.MiddlewareFunc {
return ContextTimeoutWithConfig(ContextTimeoutConfig{Timeout: timeout})
}
func ContextTimeoutWithConfig(config ContextTimeoutConfig) echo.MiddlewareFunc {
return config.ToMiddleware()
}
func (config ContextTimeoutConfig) ToMiddleware() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if config.Skipper(c) || config.Timeout == 0 {
return next(c)
}
timeoutContext, cancel := context.WithTimeout(c.Request().Context(), config.Timeout)
defer cancel()
c.SetRequest(c.Request().WithContext(timeoutContext))
err := next(c)
if err != nil && config.ErrorHandler != nil {
return config.ErrorHandler(err, c)
}
return err
}
}
}
Thanks @aldas for your valuable feedback and comments. Would you please review the updated PR? |
* remove example * remove TestContextTimeoutWithErrorMessage * remove TestContextTimeoutRecoversPanic * remove DefaultContextTimeoutConfig * add creator function * remove TestContextTimeoutWithFullEchoStack
@aldas, thanks for your comments. all change requests are completed. |
Codecov ReportBase: 92.75% // Head: 92.80% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #2380 +/- ##
==========================================
+ Coverage 92.75% 92.80% +0.05%
==========================================
Files 37 38 +1
Lines 4473 4506 +33
==========================================
+ Hits 4149 4182 +33
Misses 236 236
Partials 88 88
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
…ler execution to 5ms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coverage.coverprofile
file is added here by accident with latest commit and should be removed
👍 removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…t 100ms execution500ms
- remove unnecessary control - change sleep - change stop execution - increase timeouts golang/go#17696 Co-authored-by: @erhanakp
@aldas timeout durations increased to fix tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Just checking, was #2306 meant to be auto-closed with the merge of this? Because it's still open. |
@HeCorr , no idea. that issue is probably long running file download wrapped by timeout, that does not finish by the time context gets reused. but this is a wild guess as there are no meaningful information |
@aldas I asked because it seems @hakankutluay meant to close it together with #2379 by the way he wrote it: but the |
I closed #2306 this MW is answer for some of the problems there. |
We need to introduce a new middleware (
middleware.ContextTimeout()
) that creates context with timeout and injectsContextWithTimeout
toc.Request().Context()
. If the handler returns an error that wrapscontext.DeadlineExceeded
, it returns Service Unavailable (503)This fixes #2379, #2306.
Co-authored-by: @erhanakp