Discord radio channels: wire leases + desired-state streams (server-26#203, #204)
c2-core
- discord_streams/discord_leases wired in: POST /discord/streams,
POST /discord/guilds/{id}/stop, GET /discord/guilds/{id}/overview,
GET /discord/streams/{id}, PUT /discord/guilds/{id}/link (admin),
GET /discord/node/{node}/tokens/{id} (node key, lease holder only).
- Retained nodes/{id}/discord/desired (token ids, never token strings),
nodes/+/discord/actual subscribed and handled; per-node publish lock keeps
the retained list the newest; failed publishes retried by the reconciler.
- Tokens freed only after the node acks logout (or offline past
discord_lease_offline_release_seconds) - sweeper and C2 startup no longer
release leases.
- /nodes/{id}/command discord_join/leave map onto streams; CommandPayload
keeps preferred_token_id. /tokens: admin-only list, validate on add against
Discord, refresh, flush via transactional force release.
- Guild -> org via discord_guilds, unlinked guilds fall back to
DISCORD_UNLINKED_GUILD_ORG_ID (default "founding").
- tests/fake_firestore.py: optimistic-transaction fake; 27 lease/race tests.
discord bot
- /join, /leave, /status, autocomplete scoped to the calling guild; /leave
never touches another server; Manage Channels default permission;
/join edits its reply with the node's real result; /help copy fixed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0a724a064f
commit
a31a8df17c
@@ -210,6 +210,24 @@ class Settings(BaseSettings):
|
||||
# deployment will set this up, and skipping it must be silent.
|
||||
ai_alert_webhook_url: str = ""
|
||||
|
||||
# --- Discord radio channels (server-26#203/#204, node-26#25) -----------
|
||||
# Voice connections one node may carry at once (≈64 kbps upstream each —
|
||||
# this is what protects an LTE node).
|
||||
discord_node_max_streams: int = 4
|
||||
# Radio channels one Discord server may have on at once.
|
||||
discord_guild_max_streams: int = 4
|
||||
# How often the reconciler re-places persistent streams / retries publishes.
|
||||
discord_reconcile_interval_seconds: int = 30
|
||||
# A node offline this long has its radio-bot tokens returned to the pool.
|
||||
# MUST stay above the edge's DISCORD_MQTT_LOSS_STOP_SECONDS (default 300):
|
||||
# by then the edge has logged every radio bot out by itself, so the same
|
||||
# token can never end up logged in on two nodes.
|
||||
discord_lease_offline_release_seconds: int = 600
|
||||
# Org a Discord server that was never linked to an org (discord_guilds/{id})
|
||||
# acts for. Default keeps today's single-org deployment working unchanged;
|
||||
# set it to "" to require every server to be linked first.
|
||||
discord_unlinked_guild_org_id: str = "founding"
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user