Skip to content

server: preserve task-augmented execution after request teardown - #889

Open
juravlaleks-ctrl wants to merge 2 commits into
mark3labs:mainfrom
juravlaleks-ctrl:fix/task-augmented-request-cancel
Open

server: preserve task-augmented execution after request teardown#889
juravlaleks-ctrl wants to merge 2 commits into
mark3labs:mainfrom
juravlaleks-ctrl:fix/task-augmented-request-cancel

Conversation

@juravlaleks-ctrl

@juravlaleks-ctrl juravlaleks-ctrl commented May 16, 2026

Copy link
Copy Markdown

Description

Task-augmented tool calls created through the request handler currently inherit the request-scoped cancellation path. Once the HTTP request completes, the task goroutine can observe context canceled immediately, so tasks/get returns cancelled before the task has a chance to run.

This keeps the detached execution context limited to request-handler initiated task calls. Direct callers that invoke handleToolCall with their own cancellable parent context still preserve that cancellation behavior.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the documentation accordingly

Additional Information

  • Added a streamable HTTP regression that starts a task-augmented tool call and immediately polls tasks/get.
  • Verified with go test ./server and cd otel && go test ./....

Summary by CodeRabbit

  • Bug Fixes
    • Fixed task execution context handling to ensure task-augmented tools can continue running after the HTTP request completes, improving reliability for long-running background task operations.

Review Change Stack

@mark-iii-labs-huly

Copy link
Copy Markdown

Connected to Huly®: MCP_G-454

@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR isolates task execution context from request cancellation by introducing a task-specific context key. HandleMessage creates a non-cancelable parent context via context.WithoutCancel and stores it in the request. Task-augmented tool handlers then retrieve and use this stored context for background execution, allowing tools to complete independently of HTTP request lifecycle. A new integration test validates this behavior.

Changes

Task-augmented tool context isolation for background execution

Layer / File(s) Summary
Context key definition and request context storage
server/ctx.go, server/request_handler.go
taskExecutionParentContext constant is added. HandleMessage creates a cancellation-stripped context via context.WithoutCancel, stores it under the new key, and keeps the existing context.WithCancel wrapping for in-flight cancellation.
Task execution context selection for background goroutines
server/server.go
handleTaskAugmentedToolCall retrieves the stored task execution context from the request context (falling back to the original ctx if absent) and passes it to background goroutines executing executeTaskTool and executeRegularToolAsTask.
Integration test for request-independent task execution
server/streamable_http_test.go
Adds TestStreamableHTTP_TaskAugmentedToolSurvivesRequestCompletion which creates a blocking task, validates taskId and working status from create and tasks/get, then unblocks the tool to finish.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: preserving task-augmented execution after request teardown, which directly addresses the bug fix in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description adequately covers the bug being fixed, the type of change, and includes evidence of testing. It follows most of the template structure with Description and Type of Change sections completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/streamable_http_test.go`:
- Around line 2328-2408: Create a test cleanup to always close the release
channel: immediately after the release := make(chan struct{}) line call
t.Cleanup(func(){ close(release) }) so the channel is closed even if a require.*
fails; then remove the explicit close(release) at the end of the test (or
replace it with a safe sync.Once.close if you prefer) to avoid double-close.
This touches the release channel and the existing close(release) call in the
test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 442196c1-05de-4216-85bb-9725d40fabab

📥 Commits

Reviewing files that changed from the base of the PR and between ca26738 and 9c3a69e.

⛔ Files ignored due to path filters (1)
  • server/internal/gen/request_handler.go.tmpl is excluded by !**/gen/**
📒 Files selected for processing (4)
  • server/ctx.go
  • server/request_handler.go
  • server/server.go
  • server/streamable_http_test.go

Comment thread server/streamable_http_test.go
@juravlaleks-ctrl juravlaleks-ctrl changed the title server: keep task-augmented tools alive after request completion server: preserve task-augmented execution after request teardown May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant