perf(code): coordinate async shutdown teardown to cut exit latency - #4831
Merged
Conversation
Overlap independent shutdown phases instead of serializing them. `session.end` hooks now dispatch off the Textual event loop, agent cleanup gates server shutdown, and server stop runs concurrently with the pending-hook drain. `ServerProcess.stop()` is lock-guarded and idempotent so the teardown task and outer finally never race. Adds debug-level phase timings. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy)
marked this pull request as ready for review
July 17, 2026 19:56
This comment was marked as outdated.
This comment was marked as outdated.
Mason Daugherty (mdrxy)
pushed a commit
that referenced
this pull request
Jul 22, 2026
> [!CAUTION] > Merging this PR will automatically publish to **PyPI** and create a **GitHub release**. For the full release process, see [`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md). --- _Release notes preview: keep this section in sync with the package `CHANGELOG.md`. The published GitHub release body is extracted from the merged `CHANGELOG.md` by `release.yml`, not from this PR description._ --- ## [0.1.45](deepagents-code==0.1.44...deepagents-code==0.1.45) (2026-07-22) ### Features - Added the Hooks v2 execution engine and typed hooks data models ([#4880](#4880), [#4870](#4870)) - Added a filesystem tool allowlist for `dcode` with `--allow-fs-tools` ([#4635](#4635)) - Added a GLM-5.2 harness profile ([#4710](#4710)) - Added a built-in thread inspector skill ([#4769](#4769)) - Replaced Gemini 3.5 Flash with Gemini 3.6 Flash in the model switcher ([#4890](#4890)) - Show experimental mode in the splash screen and debug console ([#4863](#4863)) - Gate debug console click-to-copy behind a checkbox ([#4810](#4810)) ### Bug Fixes - Improved scratch-file handling by allowing cleanup of agent-created scratch files and safe OS-temp scratch artifacts ([#4860](#4860), [#4869](#4869)) - Skip grading during `/goal` proposals ([#4941](#4941)) - Improved MCP approval handling: Esc now aborts project MCP approval, disabled MCP servers are honored for plugins, remembered approvals are preserved with the env allowlist, and approvals are shared across Git worktrees ([#4888](#4888), [#4848](#4848), [#4889](#4889), [#4939](#4939)) - Hardened installer downloads and paths ([#4871](#4871)) - Fixed forced `dcode update` checks to bust the CDN cache ([#4862](#4862)) - Prevented failed exit setup from stranding the app ([#4913](#4913)) - Fixed routing so `ctrl+x` goes to the focused `ask_user` input ([#4926](#4926)) - Show `-m` prompts as queued immediately on startup ([#4861](#4861)) - Kept harness-profile diagnostics out of terminal output ([#4943](#4943)) - Avoid tracking inline restart callers ([#4894](#4894)) - Fixed debug console thread ID copying on click ([#4945](#4945)) ### Performance Improvements - Reduced exit latency by coordinating async shutdown teardown ([#4831](#4831)) - Sped up local context detection ([#4922](#4922)) _End release notes preview._ --- > [!NOTE] > A **New Contributors** section is appended to the GitHub release notes automatically at publish time (see [Release Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline), step 2). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Mason Daugherty (mdrxy)
added a commit
that referenced
this pull request
Jul 24, 2026
With `DEEPAGENTS_CODE_DEBUG` set, `dcode` again prints `Server log preserved at: <path>` to stderr after it exits. --- `perf(code): coordinate async shutdown teardown` (#4831) moved server `stop()` into the deferred `_graceful_exit()` coroutine, which runs *before* `super().exit()` restores the terminal. The `Server log preserved at:` print inside `ServerProcess._stop_process_locked` then fired while Textual still owned the alternate screen and was discarded on exit; the outer `run_textual_app` `stop()` is idempotent, so it never re-emitted the line. The fix decouples *closing the log file* (must happen during `stop()`) from *announcing the preserved path* (must happen after the terminal is restored). `_stop_process_locked` now records `_preserved_log_path`, and a new `emit_preserved_log_notice()` prints it exactly once. It is called from the terminal stop sites that run after the terminal is restored or with no TUI active (`run_textual_app` finally, `server_session` finally, `start_server_and_get_agent` finally, and `__aexit__`), and deliberately not from the hidden in-session teardown or the `/restart` path. Because the emitter clears the stored path, the interactive path's double `stop()` still yields a single visible line. Made by [Open SWE](https://openswe.vercel.app/agents/4ca951ec-5223-29f3-0312-2a0d17e26dcc) ## References - Plan: https://openswe.vercel.app/agents/4ca951ec-5223-29f3-0312-2a0d17e26dcc/plan --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Marcelo5444
pushed a commit
to Marcelo5444/deepagents
that referenced
this pull request
Jul 30, 2026
…angchain-ai#4831) Interactive shutdown is faster because independent cleanup now overlaps instead of running sequentially, without skipping any cleanup. --- `session.end` hooks run off the Textual event loop. Interrupted-agent cleanup still finishes before server shutdown; afterward, pending hooks drain while the server stops. Server stop and restart paths are synchronized to prevent duplicate or racing teardown. Existing timeouts and cleanup guarantees are unchanged, and debug logs record phase timings. Made by [Open SWE](https://openswe.vercel.app/agents/ce9a3224-140d-08bc-25d2-202982da0203) --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Marcelo5444
pushed a commit
to Marcelo5444/deepagents
that referenced
this pull request
Jul 30, 2026
> [!CAUTION] > Merging this PR will automatically publish to **PyPI** and create a **GitHub release**. For the full release process, see [`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md). --- _Release notes preview: keep this section in sync with the package `CHANGELOG.md`. The published GitHub release body is extracted from the merged `CHANGELOG.md` by `release.yml`, not from this PR description._ --- ## [0.1.45](langchain-ai/deepagents@deepagents-code==0.1.44...deepagents-code==0.1.45) (2026-07-22) ### Features - Added the Hooks v2 execution engine and typed hooks data models ([langchain-ai#4880](langchain-ai#4880), [langchain-ai#4870](langchain-ai#4870)) - Added a filesystem tool allowlist for `dcode` with `--allow-fs-tools` ([langchain-ai#4635](langchain-ai#4635)) - Added a GLM-5.2 harness profile ([langchain-ai#4710](langchain-ai#4710)) - Added a built-in thread inspector skill ([langchain-ai#4769](langchain-ai#4769)) - Replaced Gemini 3.5 Flash with Gemini 3.6 Flash in the model switcher ([langchain-ai#4890](langchain-ai#4890)) - Show experimental mode in the splash screen and debug console ([langchain-ai#4863](langchain-ai#4863)) - Gate debug console click-to-copy behind a checkbox ([langchain-ai#4810](langchain-ai#4810)) ### Bug Fixes - Improved scratch-file handling by allowing cleanup of agent-created scratch files and safe OS-temp scratch artifacts ([langchain-ai#4860](langchain-ai#4860), [langchain-ai#4869](langchain-ai#4869)) - Skip grading during `/goal` proposals ([langchain-ai#4941](langchain-ai#4941)) - Improved MCP approval handling: Esc now aborts project MCP approval, disabled MCP servers are honored for plugins, remembered approvals are preserved with the env allowlist, and approvals are shared across Git worktrees ([langchain-ai#4888](langchain-ai#4888), [langchain-ai#4848](langchain-ai#4848), [langchain-ai#4889](langchain-ai#4889), [langchain-ai#4939](langchain-ai#4939)) - Hardened installer downloads and paths ([langchain-ai#4871](langchain-ai#4871)) - Fixed forced `dcode update` checks to bust the CDN cache ([langchain-ai#4862](langchain-ai#4862)) - Prevented failed exit setup from stranding the app ([langchain-ai#4913](langchain-ai#4913)) - Fixed routing so `ctrl+x` goes to the focused `ask_user` input ([langchain-ai#4926](langchain-ai#4926)) - Show `-m` prompts as queued immediately on startup ([langchain-ai#4861](langchain-ai#4861)) - Kept harness-profile diagnostics out of terminal output ([langchain-ai#4943](langchain-ai#4943)) - Avoid tracking inline restart callers ([langchain-ai#4894](langchain-ai#4894)) - Fixed debug console thread ID copying on click ([langchain-ai#4945](langchain-ai#4945)) ### Performance Improvements - Reduced exit latency by coordinating async shutdown teardown ([langchain-ai#4831](langchain-ai#4831)) - Sped up local context detection ([langchain-ai#4922](langchain-ai#4922)) _End release notes preview._ --- > [!NOTE] > A **New Contributors** section is appended to the GitHub release notes automatically at publish time (see [Release Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline), step 2). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Marcelo5444
pushed a commit
to Marcelo5444/deepagents
that referenced
this pull request
Jul 30, 2026
…hain-ai#4999) With `DEEPAGENTS_CODE_DEBUG` set, `dcode` again prints `Server log preserved at: <path>` to stderr after it exits. --- `perf(code): coordinate async shutdown teardown` (langchain-ai#4831) moved server `stop()` into the deferred `_graceful_exit()` coroutine, which runs *before* `super().exit()` restores the terminal. The `Server log preserved at:` print inside `ServerProcess._stop_process_locked` then fired while Textual still owned the alternate screen and was discarded on exit; the outer `run_textual_app` `stop()` is idempotent, so it never re-emitted the line. The fix decouples *closing the log file* (must happen during `stop()`) from *announcing the preserved path* (must happen after the terminal is restored). `_stop_process_locked` now records `_preserved_log_path`, and a new `emit_preserved_log_notice()` prints it exactly once. It is called from the terminal stop sites that run after the terminal is restored or with no TUI active (`run_textual_app` finally, `server_session` finally, `start_server_and_get_agent` finally, and `__aexit__`), and deliberately not from the hidden in-session teardown or the `/restart` path. Because the emitter clears the stored path, the interactive path's double `stop()` still yields a single visible line. Made by [Open SWE](https://openswe.vercel.app/agents/4ca951ec-5223-29f3-0312-2a0d17e26dcc) ## References - Plan: https://openswe.vercel.app/agents/4ca951ec-5223-29f3-0312-2a0d17e26dcc/plan --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Interactive shutdown is faster because independent cleanup now overlaps instead of running sequentially, without skipping any cleanup.
session.endhooks run off the Textual event loop. Interrupted-agent cleanup still finishes before server shutdown; afterward, pending hooks drain while the server stops.Server stop and restart paths are synchronized to prevent duplicate or racing teardown. Existing timeouts and cleanup guarantees are unchanged, and debug logs record phase timings.
Made by Open SWE