Skip to content

fix(telegram): replace SIGTERM dedup with atomic lock + follower mode#1374

Closed
thewusman2025 wants to merge 1 commit intoanthropics:mainfrom
thewusman2025:fix/telegram-yield-not-kill
Closed

fix(telegram): replace SIGTERM dedup with atomic lock + follower mode#1374
thewusman2025 wants to merge 1 commit intoanthropics:mainfrom
thewusman2025:fix/telegram-yield-not-kill

Conversation

@thewusman2025
Copy link
Copy Markdown

Summary

  • Replaces the v0.0.5 bot.pid SIGTERM mechanism with an atomic exclusive-create lock file (O_CREAT|O_EXCL via fs.openSync('wx')). When a second instance starts and the lock holder is alive, it yields into follower mode instead of killing the existing poller — preserving the active MCP pipe.
  • Follower mode: skips bot.start() (no polling), calls getMe() for bot identity, keeps all outbound MCP tools active (reply, edit_message, react, download_attachment) since they use bot.api.* which doesn't require a polling loop.
  • Dead holder reclaim: if the lock file points to a dead PID (kill(pid, 0) throws), the stale lock is removed and the new instance becomes leader.
  • Lock cleanup on shutdown: only removes poll.lock if owned by this process, matching v0.0.5's existing pattern.

Problem

The v0.0.5 bot.pid mechanism (#1349) SIGTERMs any existing poller on startup. This was intended to clear zombies, but it kills the MCP pipe of legitimate concurrent sessions — cron-fired sessions kill the interactive session's poller (#1360), and the dual-load bug (#1344) causes the second load to kill the first (#1363).

What changed

Before (v0.0.5) After
Read bot.pid, SIGTERM holder, claim slot Atomic openSync('wx') — fails if lock exists
Second instance always kills first Second instance yields, runs follower mode
MCP pipe breaks on dual-load MCP pipe preserved, outbound tools stay active
No follower concept Leader polls, followers serve outbound tools

Test plan

  • Single session: starts as leader, polls normally, lock file created
  • Second session (same token): detects live leader, enters follower mode, outbound reply works
  • Leader exits: lock file removed, next session becomes leader
  • Orphan recovery: kill leader with SIGKILL (lock file stays), new session reclaims stale lock
  • Dual-load (Telegram plugin: duplicate pollers cause background CPU churn even when idle #1344): second load yields without killing first

Fixes #1360, #1363. Related: #1344.

🤖 Generated with Claude Code

The v0.0.5 bot.pid mechanism SIGTERMs any existing poller on startup,
which kills the MCP pipe of legitimate concurrent sessions (anthropics#1360, anthropics#1363).

Replace with an atomic exclusive-create lock file (O_CREAT|O_EXCL).
If the lock holder is alive, the new instance yields into follower mode
— outbound tools (reply, edit, react, download) remain active via
bot.api, only polling is skipped. Dead holders are reclaimed normally.

Three changes:
- acquirePollLock() using fs.openSync('wx') instead of SIGTERM
- Follower mode: skip bot.start(), call getMe() for outbound tools
- Lock cleanup on shutdown (only if owned by this process)

Fixes anthropics#1360, anthropics#1363. Related: anthropics#1344.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Thanks for your interest! This repo only accepts contributions from Anthropic team members. If you'd like to submit a plugin to the marketplace, please submit your plugin here.

@github-actions github-actions bot closed this Apr 12, 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.

telegram v0.0.5: stale-poller SIGTERM kills legitimate concurrent sessions (regression from #1075 fix)

1 participant