fix: decouple context for activities - #2754
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Graphite Automations"Warn authors when publishing large PRs" took an action on this PR • (05/28/26)1 teammate was notified to this PR based on Kyle Mendell's automation. |
| if writeErr != nil && (w.activityService == nil || w.activityID == "") { | ||
| return 0, writeErr | ||
| } | ||
|
|
||
| return len(p), nil |
There was a problem hiding this comment.
Dead-code error-propagation branch
NewWriter already returns the raw writer (bypassing *Writer entirely) when activityService == nil || activityID == "", so any call to (*Writer).Write has w.activityService != nil and w.activityID != "" by construction. The condition w.activityService == nil || w.activityID == "" is therefore always false inside this method, making the return 0, writeErr branch unreachable. All HTTP write errors are unconditionally swallowed when a *Writer is in use — which appears to be the intended design — but the guard reads as meaningful protection that isn't actually exercised.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/pkg/libarcane/activity/writer.go
Line: 101-105
Comment:
**Dead-code error-propagation branch**
`NewWriter` already returns the raw writer (bypassing `*Writer` entirely) when `activityService == nil || activityID == ""`, so any call to `(*Writer).Write` has `w.activityService != nil` and `w.activityID != ""` by construction. The condition `w.activityService == nil || w.activityID == ""` is therefore always `false` inside this method, making the `return 0, writeErr` branch unreachable. All HTTP write errors are unconditionally swallowed when a `*Writer` is in use — which appears to be the intended design — but the guard reads as meaningful protection that isn't actually exercised.
How can I resolve this? If you propose a fix, please make it concise.6fa8c80 to
8d1124d
Compare
8d1124d to
8306633
Compare

Checklist
mainbranchWhat This PR Implements
Fixes:
Changes Made
Testing Done
./scripts/development/dev.sh startjust lint all)just test backendAI Tool Used (if applicable)
AI Tool:
Assistance Level:
What AI helped with:
I reviewed and edited all AI-generated output:
I ran all required tests and manually verified changes:
Additional Context
Disclaimer Greptiles Reviews use AI, make sure to check over its work.
To better help train Greptile on our codebase, if the comment is useful and valid Like the comment, if its not helpful or invalid Dislike
To have Greptile Re-Review the changes, mention
greptileai.Greptile Summary
This PR decouples activity tracking from HTTP request context by introducing an
ActivityRuntimeContextutility and anActivityAppContextwrapper that propagate the app lifecycle context through handler registration, replacing per-requestcontext.WithoutCancelcalls.ActivityRuntimeContextselects the app lifecycle context (frombootstrap.go, marked viaWithAppLifecycleContext) when available, so background activity goroutines — particularlyWriter.drainMessagesInternal— now exit cleanly on app shutdown instead of leaking indefinitely under the old never-donecontext.WithoutCancelcontext.completeImageUpdateActivityInternalcall ong.Wait()failure inImageUpdateService.CheckMultipleImagesis fixed, preventing activities from being permanently stuck in a running state after a batch error.Confidence Score: 5/5
Safe to merge; the decoupling design is sound and closes a goroutine-lifetime bug in the activity writer.
The goroutine-lifetime fix in the writer drain loop is correct: using the app lifecycle context instead of a never-done context.WithoutCancel means the background goroutine exits on app shutdown. The ActivityRuntimeContext helper is well-tested and the fallback chain is sensible. The one concern — that returning the app context directly drops request-scoped tracing/logging values — is a deliberate design trade-off for the decoupling goal, but worth tracking if the team later adds distributed tracing via context propagation.
backend/pkg/utils/activity_context.go — the direct return of appCtx loses request-scoped observability values; worth revisiting if OpenTelemetry or similar context-propagated tracing is added.
Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "fix: decouple context for activities" | Re-trigger Greptile