Summary
All HTTP methods in ControlPlaneMemoryBackend use http.NewRequest instead of http.NewRequestWithContext, so a cancelled execution context cannot cancel in-flight memory I/O, causing 15-second hangs on timeout.
Context
control_plane_memory_backend.go at lines 59, 88, 125, and 153 construct HTTP requests without a context. The MemoryBackend interface itself also lacks context.Context parameters. When an agent execution is cancelled (user abort, workflow timeout, health-check failure), the in-flight Set/Get/Delete/List HTTP calls to the control plane will continue running until the 15s http.Client timeout fires. Under load, this means cancelled executions hold HTTP connections and goroutines for up to 15 seconds after they should have been cleaned up.
Scope
In Scope
- Add
context.Context as the first parameter to all MemoryBackend interface methods (Set, Get, Delete, List, SetVector, GetVector, etc.).
- Update all interface implementations (
InMemoryBackend, ControlPlaneMemoryBackend, any test mocks) to accept and propagate the context.
- Use
http.NewRequestWithContext(ctx, ...) in ControlPlaneMemoryBackend for all four HTTP methods.
- Update all callers in the agent SDK to pass the execution context through to memory operations.
Out of Scope
- Changing the HTTP client timeout value — that is a separate tuning concern.
- Implementing retry logic on context cancellation.
- Fixing the deep-copy race in
InMemoryBackend — tracked separately in G1.
Files
sdk/go/agent/memory.go — add ctx context.Context to MemoryBackend interface and InMemoryBackend implementation
sdk/go/agent/control_plane_memory_backend.go:59,88,125,153 — switch to http.NewRequestWithContext
sdk/go/agent/agent.go — update callers that invoke memory backend methods to pass execution context
sdk/go/agent/memory_test.go — add test: cancelling context before Get causes the call to return context.Canceled
Acceptance Criteria
Notes for Contributors
Severity: HIGH
This is an interface-breaking change — all callers and mocks must be updated. Search for MemoryBackend usages across sdk/go/ with grep -r 'MemoryBackend' sdk/go/ to find all sites. The InMemoryBackend can accept the context but ignore it (operations are in-memory and non-blocking); the context parameter is there for interface consistency and future use.
Summary
All HTTP methods in
ControlPlaneMemoryBackendusehttp.NewRequestinstead ofhttp.NewRequestWithContext, so a cancelled execution context cannot cancel in-flight memory I/O, causing 15-second hangs on timeout.Context
control_plane_memory_backend.goat lines 59, 88, 125, and 153 construct HTTP requests without a context. TheMemoryBackendinterface itself also lackscontext.Contextparameters. When an agent execution is cancelled (user abort, workflow timeout, health-check failure), the in-flightSet/Get/Delete/ListHTTP calls to the control plane will continue running until the 15shttp.Clienttimeout fires. Under load, this means cancelled executions hold HTTP connections and goroutines for up to 15 seconds after they should have been cleaned up.Scope
In Scope
context.Contextas the first parameter to allMemoryBackendinterface methods (Set,Get,Delete,List,SetVector,GetVector, etc.).InMemoryBackend,ControlPlaneMemoryBackend, any test mocks) to accept and propagate the context.http.NewRequestWithContext(ctx, ...)inControlPlaneMemoryBackendfor all four HTTP methods.Out of Scope
InMemoryBackend— tracked separately in G1.Files
sdk/go/agent/memory.go— addctx context.ContexttoMemoryBackendinterface andInMemoryBackendimplementationsdk/go/agent/control_plane_memory_backend.go:59,88,125,153— switch tohttp.NewRequestWithContextsdk/go/agent/agent.go— update callers that invoke memory backend methods to pass execution contextsdk/go/agent/memory_test.go— add test: cancelling context beforeGetcauses the call to returncontext.CanceledAcceptance Criteria
MemoryBackendinterface methods all acceptcontext.Contextas first parameterControlPlaneMemoryBackenduseshttp.NewRequestWithContextfor all requestscontext.Canceledorcontext.DeadlineExceededgo test ./sdk/go/...)make lint)Notes for Contributors
Severity: HIGH
This is an interface-breaking change — all callers and mocks must be updated. Search for
MemoryBackendusages acrosssdk/go/withgrep -r 'MemoryBackend' sdk/go/to find all sites. TheInMemoryBackendcan accept the context but ignore it (operations are in-memory and non-blocking); the context parameter is there for interface consistency and future use.