CI / backend (push) Canceled after 0s
上一版把双进程抢会话修了,但生产重启后仍然不收消息:`start_all()` 是进程启动时的
查询,那一刻没有工作区上下文,`bot_channel` 的 RLS 把行全藏起来,一行都查不到,
于是"页面上显示已连接,实际上没人在拉消息"。
- 迁移 0016 补一条只读策略:`current_setting('app.bot_list') = 'on'` 时允许 SELECT
(只开 SELECT,防止顺手拿它改别人的通道);
- `start_all()` 走 `active_channel_ids()`,先设这个 GUC 再列通道;
- 补测试 `test_startup_sees_logged_in_channels`。
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""启动时列出要接管的通道,也需要一条 RLS 口子
|
||
|
||
Revision ID: 0016
|
||
Revises: 0015
|
||
Create Date: 2026-11-05
|
||
|
||
`BotManager.start_all()` 要在进程启动时问一句"现在有哪些通道已登录、该接着收消息",
|
||
但 `bot_channel` 的隔离策略要求 `workspace_id = app_ws_id()`,启动那一刻**没有工作区**,
|
||
结果一行都查不到——表现是"重启之后机器人静默不收消息,页面上还显示已连接"。
|
||
|
||
0014 那条口子是"知道 id、只看自己那一行",这里补的是"允许列出还没开始干的活":
|
||
只有当次事务显式设了 `app.bot_list = 'on'` 时才放行,而且只开 **SELECT**,
|
||
防止有人顺手拿它改别人的通道。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from collections.abc import Sequence
|
||
|
||
from alembic import op
|
||
|
||
from app.roles import APP_ROLE
|
||
|
||
revision: str = "0016"
|
||
down_revision: str = "0015"
|
||
branch_labels: Sequence[str] | None = None
|
||
depends_on: Sequence[str] | None = None
|
||
|
||
CREATE_POLICY = """
|
||
CREATE POLICY bot_channel_startup ON bot_channel
|
||
FOR SELECT
|
||
USING (current_setting('app.bot_list', true) = 'on')
|
||
"""
|
||
|
||
|
||
def upgrade() -> None:
|
||
op.execute("DROP POLICY IF EXISTS bot_channel_startup ON bot_channel")
|
||
op.execute(CREATE_POLICY)
|
||
op.execute(f"GRANT SELECT ON bot_channel TO {APP_ROLE}")
|
||
|
||
|
||
def downgrade() -> None:
|
||
op.execute("DROP POLICY IF EXISTS bot_channel_startup ON bot_channel")
|