Skip to content

fix: acquire session lock in background and cron wake paths - #9671

Open
T52T52 wants to merge 3 commits into
AstrBotDevs:masterfrom
T52T52:fix/background-wake-session-lock
Open

fix: acquire session lock in background and cron wake paths#9671
T52T52 wants to merge 3 commits into
AstrBotDevs:masterfrom
T52T52:fix/background-wake-session-lock

Conversation

@T52T52

@T52T52 T52T52 commented Aug 13, 2026

Copy link
Copy Markdown

问题
后台任务唤醒路径(wakemainagentforbackgroundresult)和定时任务唤醒路径(wokemain_agent)都绕过了 sessionlockmanager,导致同一会话的 agent 工作流与用户消息处理并发执行,造成:

  • LLM 上下文过期(第二个请求看不到第一个请求的内容)
  • 对话历史丢失(persistagenthistory 中并发读改写互相覆盖)

复现步骤
1.让llm同时调用两个或以上子agent
2. 多个子 agent 同时返回结果,主 agent 的唤醒路径并发触发
3.历史被覆盖,llm只有最后一个子agent回复的上下文

根因
用户消息处理路径(agentsubstages/internal.py)将整个 agent 流程包在 sessionlockmanager.acquirelock(unifiedmsg_origin) 中,但两条唤醒路径直接调用 buildmainagent,没有获取会话锁。

修复
将两条唤醒路径的「读取-构建-运行-持久化」流程包进 per-session 锁中,与用户消息路径保持一致。

测试

  • tests/testbackgroundwake_lock.py
  • tests/testcronwake_lock.py
  • tests/testpersistrace.py

全部 4 个测试通过。修复前 testbackgroundwake_lock 和 testcronwake_lock 失败(acquirelock 调用 0 次),testpersistrace 丢失 3/4 并发结果。

Summary by Sourcery

Guard background and cron agent wake workflows with per-session locking to prevent concurrent access to conversation history.

Bug Fixes:

  • Ensure background-task wake path acquires the session lock before reading, running the main agent, and persisting history.
  • Ensure cron wake path acquires the session lock before reading, running the main agent, and persisting history.
  • Prevent loss of conversation context and assistant results caused by racing writes to persisted agent history.

Tests:

  • Add regression tests confirming background wake acquires the session lock and no longer runs agents without session serialization.
  • Add regression tests confirming cron wake acquires the session lock and respects per-session serialization.
  • Add a concurrency regression test for persist_agent_history to verify that multiple concurrent writes preserve all results in the session history.

T52T52 added 3 commits August 14, 2026 03:28
The background wake path (_wake_main_agent_for_background_result)
bypassed session_lock_manager, so it could run concurrently with
user message processing on the same conversation, causing stale
LLM context and lost conversation history (persist race).

Wrap the read-build-run-persist flow in the per-session lock,
matching the user message path in internal.py.

- test_background_wake_lock: asserts acquire_lock is called
- test_persist_race: verifies the lock prevents concurrent overwrites
The cron wake path (_woke_main_agent) also bypassed session_lock_manager,
running concurrently with user message processing on the same conversation.
Wrap the read-build-run-persist flow in the per-session lock, matching
the user message path in internal.py.

- test_cron_wake_lock: asserts acquire_lock is called
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Aug 13, 2026

@sourcery-ai sourcery-ai 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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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

Labels

area:core The bug / feature is about astrbot's core, backend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant