-
Notifications
You must be signed in to change notification settings - Fork 5
feat(profiling): Add 30-second timeout for chunk downloads #664
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,13 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "encoding/json" | ||
| "errors" | ||
| "fmt" | ||
| "net/http" | ||
| "strconv" | ||
| "time" | ||
|
|
||
| "github.com/getsentry/sentry-go" | ||
| "github.com/google/uuid" | ||
|
|
@@ -43,6 +45,8 @@ type postProfileFromChunkIDsResponse struct { | |
| // body request, we use a POST method instead (similarly to the flamegraph endpoint). | ||
| func (env *environment) postProfileFromChunkIDs(w http.ResponseWriter, r *http.Request) { | ||
| ctx := r.Context() | ||
| downloadContext, cancel := context.WithTimeout(ctx, 30*time.Second) | ||
| defer cancel() | ||
| hub := sentry.GetHubFromContext(ctx) | ||
| ps := httprouter.ParamsFromContext(ctx) | ||
| rawOrganizationID := ps.ByName("organization_id") | ||
|
|
@@ -87,7 +91,7 @@ func (env *environment) postProfileFromChunkIDs(w http.ResponseWriter, r *http.R | |
| go func() { | ||
| for _, ID := range requestBody.ChunkIDs { | ||
| readJobs <- chunk.ReadJob{ | ||
| Ctx: ctx, | ||
| Ctx: downloadContext, | ||
| Storage: env.storage, | ||
| OrganizationID: organizationID, | ||
| ProjectID: projectID, | ||
|
|
@@ -127,6 +131,10 @@ func (env *environment) postProfileFromChunkIDs(w http.ResponseWriter, r *http.R | |
| w.WriteHeader(http.StatusNotFound) | ||
| return | ||
| } | ||
| if errors.Is(err, context.Canceled) { | ||
| w.WriteHeader(http.StatusServiceUnavailable) | ||
| return | ||
| } | ||
|
Comment on lines
+134
to
+137
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: The new timeout error handling only checks for Suggested FixAdd a check for Prompt for AI AgentDid we get this right? 👍 / 👎 to inform future reviews. |
||
| var e *googleapi.Error | ||
| if ok := errors.As(err, &e); ok { | ||
| hub.Scope().SetContext("Google Cloud Storage Error", map[string]interface{}{ | ||
|
|
@@ -292,6 +300,10 @@ func (env *environment) getRawChunk(w http.ResponseWriter, r *http.Request) { | |
| w.WriteHeader(http.StatusNotFound) | ||
| return | ||
| } | ||
| if errors.Is(err, context.Canceled) { | ||
| w.WriteHeader(http.StatusServiceUnavailable) | ||
| return | ||
| } | ||
| var e *googleapi.Error | ||
| if ok := errors.As(err, &e); ok { | ||
| hub.Scope().SetContext("Google Cloud Storage Error", map[string]interface{}{ | ||
|
|
||
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.
Timeout produces DeadlineExceeded, not Canceled error
High Severity
The
downloadContextis created withcontext.WithTimeout, which producescontext.DeadlineExceededwhen the 30-second timeout fires. However, the error check only matchescontext.Canceled. This means timeout errors will bypass the 503 handler and fall through to the generic 500 path, getting reported to Sentry — the exact problem this PR aims to fix. The existing flamegraph code correctly checks forcontext.DeadlineExceededin the same scenario.