fix: store token lock identity at acquire time for Slack and Discord

Community review (devoruncommented) correctly identified that the Slack
adapter re-read SLACK_APP_TOKEN from os.getenv() during disconnect,
which could differ from the value used during connect if the environment
changed. Discord had the same pattern with self.config.token (less risky
but still not bulletproof).

Both now follow the Telegram pattern: store the token identity on self
at acquire time, use the stored value for release, clear after release.

Also fixes docs: alias naming was hermes-<name> in docs but actual
implementation creates <name> directly (e.g. ~/.local/bin/coder not
~/.local/bin/hermes-coder).
This commit is contained in:
Teknium
2026-03-29 11:09:17 -07:00
parent b151d5f7a7
commit 442888a05b
2 changed files with 10 additions and 6 deletions

View File

@@ -488,7 +488,8 @@ class DiscordAdapter(BasePlatformAdapter):
try:
# Acquire scoped lock to prevent duplicate bot token usage
from gateway.status import acquire_scoped_lock
acquired, existing = acquire_scoped_lock('discord-bot-token', self.config.token, metadata={'platform': 'discord'})
self._token_lock_identity = self.config.token
acquired, existing = acquire_scoped_lock('discord-bot-token', self._token_lock_identity, metadata={'platform': 'discord'})
if not acquired:
owner_pid = existing.get('pid') if isinstance(existing, dict) else None
message = f'Discord bot token already in use' + (f' (PID {owner_pid})' if owner_pid else '') + '. Stop the other gateway first.'
@@ -652,7 +653,9 @@ class DiscordAdapter(BasePlatformAdapter):
# Release the token lock
try:
from gateway.status import release_scoped_lock
release_scoped_lock('discord-bot-token', self.config.token)
if getattr(self, '_token_lock_identity', None):
release_scoped_lock('discord-bot-token', self._token_lock_identity)
self._token_lock_identity = None
except Exception:
pass

View File

@@ -95,6 +95,7 @@ class SlackAdapter(BasePlatformAdapter):
try:
# Acquire scoped lock to prevent duplicate app token usage
from gateway.status import acquire_scoped_lock
self._token_lock_identity = app_token
acquired, existing = acquire_scoped_lock('slack-app-token', app_token, metadata={'platform': 'slack'})
if not acquired:
owner_pid = existing.get('pid') if isinstance(existing, dict) else None
@@ -149,12 +150,12 @@ class SlackAdapter(BasePlatformAdapter):
logger.warning("[Slack] Error while closing Socket Mode handler: %s", e, exc_info=True)
self._running = False
# Release the token lock
# Release the token lock (use stored identity, not re-read env)
try:
from gateway.status import release_scoped_lock
app_token = os.getenv("SLACK_APP_TOKEN")
if app_token:
release_scoped_lock('slack-app-token', app_token)
if getattr(self, '_token_lock_identity', None):
release_scoped_lock('slack-app-token', self._token_lock_identity)
self._token_lock_identity = None
except Exception:
pass