Skip to content

fix(kanban,send_message): 看板进程锁 + 钉钉 Markdown webhook / kanban flock + DingTalk markdown#37292

Closed
WenhuaXia wants to merge 1 commit into
NousResearch:mainfrom
WenhuaXia:fix/kanban-flock-and-dingtalk-markdown
Closed

fix(kanban,send_message): 看板进程锁 + 钉钉 Markdown webhook / kanban flock + DingTalk markdown#37292
WenhuaXia wants to merge 1 commit into
NousResearch:mainfrom
WenhuaXia:fix/kanban-flock-and-dingtalk-markdown

Conversation

@WenhuaXia

Copy link
Copy Markdown

看板 SQLite 跨进程写锁 + 钉钉 Webhook Markdown 渲染

Kanban SQLite Cross-Process Write Lock + DingTalk Markdown Webhook

看板 WAL 损坏问题 / Kanban WAL Corruption

问题 / Problem: 多个 kanban worker 进程并发写入同一 SQLite 数据库导致频繁 WAL 损坏(33 分钟内 7 次)。SQLite WAL + busy_timeout 只能保护同一进程内的并发线程,跨进程仍会竞争 BEGIN IMMEDIATE 导致页面损坏。

Problem: Multiple kanban worker processes writing concurrently to the same SQLite database caused frequent WAL corruption (7 times in 33 minutes). SQLite WAL + busy_timeout only protects concurrent threads within the same process; cross-process races through BEGIN IMMEDIATE can corrupt WAL pages.

修复 / Fix:

  1. connect() 后打开 .db.lock 文件,write_txn() 用 fcntl.flock(LOCK_EX) 包裹整个事务,确保同一时间只有一个进程在写。

  2. schema init 也获取 .db.lock(不只是 .init.lock),防止 DDL/DML 竞争。

  3. Windows 或 fcntl 不可用时优雅降级为 no-op。

  4. After connect(), open .db.lock. Every write_txn() acquires fcntl.flock(LOCK_EX) around the entire transaction.

  5. Schema init also acquires .db.lock to prevent DDL/DML races.

  6. Graceful fallback on Windows or when fcntl is unavailable.

钉钉 Markdown 渲染 / DingTalk Markdown Rendering

问题 / Problem: standalone cron delivery 用 msgtype:"text" 发钉钉消息,markdown 表格中的管道符显示为文字。live adapter 用 msgtype:"markdown" 正确渲染。

Problem: Standalone cron delivery sent msgtype:"text" for DingTalk, which does not render markdown tables. The live adapter uses msgtype:"markdown" which renders correctly.

修复 / Fix: 统一使用 msgtype:"markdown",被拒绝时 fallback 到纯文本。

Fix: Use msgtype:"markdown" consistently with fallback to plain text.

Changes

  • hermes_cli/kanban_db.py: fcntl flock for inter-process write safety
  • tools/send_message_tool.py: markdown msgtype for DingTalk standalone delivery

References

…+ DingTalk markdown webhook

看板 SQLite 跨进程写锁(inter-process flock):
Kanban SQLite cross-process write lock (inter-process flock):

问题:多个 kanban worker 进程并发写入同一 SQLite 数据库导致
WAL 损坏。SQLite WAL + busy_timeout 只能保护同一进程内的
并发线程,跨进程仍会竞争 BEGIN IMMEDIATE 导致页面损坏。

Problem: Multiple kanban worker processes writing concurrently to the
same SQLite database caused frequent WAL corruption. SQLite WAL +
busy_timeout only protects concurrent threads within the same process;
cross-process races through BEGIN IMMEDIATE can corrupt WAL pages.

修复:
Fix:
1. connect() 后打开 .db.lock 文件,write_txn() 用 fcntl.flock(LOCK_EX)
   包裹整个事务,确保同一时间只有一个进程在写。
2. schema init 也获取 .db.lock(不只是 .init.lock),防止 DDL/DML 竞争。
3. Windows 或 fcntl 不可用时优雅降级为 no-op。

1. After connect(), open a .db.lock file. Every write_txn() acquires
   fcntl.flock(LOCK_EX) around the entire transaction, ensuring only one
   process writes at a time.
2. Schema init also acquires .db.lock (not just .init.lock) to prevent
   DDL/DML races.
3. Graceful fallback on Windows or when fcntl is unavailable.

钉钉 webhook Markdown 渲染:
DingTalk webhook Markdown rendering:

问题:standalone cron delivery 用 msgtype:"text" 发钉钉消息,markdown
表格中的管道符显示为文字。live adapter 用 msgtype:"markdown" 正确渲染。

Problem: Standalone cron delivery sent msgtype:"text" for DingTalk, which
does not render markdown tables — pipes show as literal characters. The
live DingTalk adapter sends msgtype:"markdown" which renders tables correctly.

修复:统一使用 msgtype:"markdown",被拒绝时 fallback 到纯文本。
Fix: Use msgtype:"markdown" consistently with fallback to plain text
if the API rejects the markdown payload.

Changes:
- hermes_cli/kanban_db.py: fcntl flock for inter-process write safety
- tools/send_message_tool.py: markdown msgtype for DingTalk standalone delivery

Related: NousResearch#35787 (closed), NousResearch#34400 (closed)
@WenhuaXia WenhuaXia force-pushed the fix/kanban-flock-and-dingtalk-markdown branch from c074c81 to 53fe79c Compare June 2, 2026 08:10
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins platform/dingtalk DingTalk adapter labels Jun 2, 2026
@WenhuaXia

Copy link
Copy Markdown
Author

Split into two separate PRs: kanban flock and DingTalk markdown.

@WenhuaXia WenhuaXia closed this Jun 2, 2026
WenhuaXia added a commit to WenhuaXia/hermes-agent that referenced this pull request Jun 6, 2026
…alk standalone webhook

问题 / Problem: standalone cron delivery 用 msgtype:"text" 发钉钉消息,markdown
表格中的管道符显示为文字。live adapter 用 msgtype:"markdown" 正确渲染。

Problem: Standalone cron delivery sent msgtype:"text" for DingTalk, which does
not render markdown tables — pipes show as literal characters. The live
DingTalk adapter sends msgtype:"markdown" which renders tables correctly.

修复 / Fix: 统一使用 msgtype:"markdown",被拒绝时 fallback 到纯文本。
Fix: Use msgtype:"markdown" consistently with fallback to plain text if the
API rejects the markdown payload.

Changes:
- tools/send_message_tool.py: markdown msgtype for DingTalk standalone delivery

Related: NousResearch#34400 (closed), NousResearch#37292 (closed, split)
WenhuaXia added a commit to WenhuaXia/hermes-agent that referenced this pull request Jun 6, 2026
…vent DB corruption

问题 / Problem: 多个 kanban worker 进程并发写入同一 SQLite 数据库导致频繁
WAL 损坏(33 分钟内 7 次)。SQLite WAL + busy_timeout 只能保护同一进程内的
并发线程,跨进程仍会竞争 BEGIN IMMEDIATE 导致页面损坏。

Problem: Multiple kanban worker processes writing concurrently to the same
SQLite database caused frequent WAL corruption (7 times in 33 minutes).
SQLite WAL + busy_timeout only protects concurrent threads within the same
process; cross-process races through BEGIN IMMEDIATE can corrupt WAL pages.

修复 / Fix:
1. connect() 后打开 .db.lock 文件,write_txn() 用 fcntl.flock(LOCK_EX)
   包裹整个事务,确保同一时间只有一个进程在写。
2. schema init 也获取 .db.lock(不只是 .init.lock),防止 DDL/DML 竞争。
3. Windows 或 fcntl 不可用时优雅降级为 no-op。

1. After connect(), open a .db.lock file. Every write_txn() acquires
   fcntl.flock(LOCK_EX) around the entire transaction, ensuring only one
   process writes at a time.
2. Schema init also acquires .db.lock (not just .init.lock) to prevent
   DDL/DML races.
3. Graceful fallback on Windows or when fcntl is unavailable.

Changes:
- hermes_cli/kanban_db.py: fcntl flock for inter-process write safety

Related: NousResearch#35787 (closed), NousResearch#37292 (closed, split)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have platform/dingtalk DingTalk adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants