Skip to content

Fix InMemoryMcpTaskStore TTL clocks, cancel CAS, and missing-task throws - #1965

Open
robertmclaws wants to merge 2 commits into
modelcontextprotocol:mainfrom
CloudNimble:fix/in-memory-task-store-ttl-windows
Open

robertmclaws wants to merge 2 commits into
modelcontextprotocol:mainfrom
CloudNimble:fix/in-memory-task-store-ttl-windows

Conversation

@robertmclaws

Copy link
Copy Markdown

Fixes #1963.

InMemoryMcpTaskStore mixed work and tracking into one CreatedAt + TTL clock, threw on missing mutations, could report a successful cancel that lost the CAS, swept the dictionary on the create thread before inserting, and ignored CancellationToken.

Changes

  1. SetCancelledAsync return value — transitioned is reset on the terminal/expired retry so a lost CAS against complete/fail no longer returns true.
  2. Missing tasks — TryUpdate returns false instead of throwing. Cancel returns false; complete/fail/input are no-ops.
  3. Work vs track clocks — IsActive is the work window (CreatedAt + TTL). Never-terminal rows stay visible until CreatedAt + 2×TTL so a late complete/fail/cancel can still be recorded. Terminal rows stay visible until LastUpdatedAt + TTL. GetTaskAsync serves a terminal snapshot and then drops the row. Null/non-positive TTL remains unlimited until a terminal get.
  4. Sweep — insert the new snapshot first, then sweep. GetTaskAsync pulses the same throttled walk. Sweep removes only HasExpired rows.
  5. CancellationToken — observed at the start of every public method, in TryUpdate, and during the sweep walk so a cancelled caller does not finish the dictionary scan or commit.

Also adds a TimeProvider constructor (default TimeProvider.System) so TTL and sweep can be tested with FakeTimeProvider.

Tests

xUnit coverage of InMemoryMcpTaskStore is 100% line and branch, including unhappy paths (missing keys, second-window work refused / settle allowed, serve-and-drop, cancelled tokens, CAS retry). Integration tests that polled a completed task and then got it again now expect the post-drop unknown-task error; cancel is still acknowledged and does not resurrect a row.

…ows (modelcontextprotocol#1963)

Split work vs tracking windows, serve-and-drop terminal Gets, insert then
sweep, honor CancellationToken, and treat missing mutations as no-ops.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant