Ensure runtime IM channels are ready after restart

This commit is contained in:
taohe
2026-06-11 22:19:03 +08:00
parent 7ce047b723
commit b17bc5efc9
4 changed files with 191 additions and 7 deletions
@@ -247,6 +247,60 @@ def test_get_providers_reports_configured_channel_not_running(tmp_path, monkeypa
anyio.run(repo.close)
def test_get_providers_restarts_configured_channel_when_service_can_reconcile(tmp_path, monkeypatch):
import anyio
repo = anyio.run(_make_repo, tmp_path)
config = ChannelConnectionsConfig.model_validate(
{
"enabled": True,
"feishu": {"enabled": True},
}
)
channels_config = {
"feishu": {
"enabled": True,
"app_id": "feishu-app",
"app_secret": "feishu-secret",
}
}
app = _make_app(config, repo, channels_config)
status = {
"service_running": True,
"channels": {
"feishu": {
"enabled": True,
"running": False,
}
},
}
reconciled: list[tuple[str, dict]] = []
async def ensure_channel_ready(provider, runtime_config):
reconciled.append((provider, dict(runtime_config)))
status["channels"][provider]["running"] = True
return True
service = SimpleNamespace(
get_status=lambda: status,
ensure_channel_ready=ensure_channel_ready,
)
monkeypatch.setattr("app.channels.service.get_channel_service", lambda: service)
with TestClient(app) as client:
response = client.get("/api/channels/providers")
assert response.status_code == 200
by_provider = {item["provider"]: item for item in response.json()["providers"]}
assert by_provider["feishu"]["configured"] is True
assert by_provider["feishu"]["connectable"] is True
assert by_provider["feishu"]["connection_status"] == "connected"
assert by_provider["feishu"]["unavailable_reason"] is None
assert reconciled == [("feishu", channels_config["feishu"])]
anyio.run(repo.close)
def test_get_providers_uses_newest_connection_status_per_provider(tmp_path):
import anyio
+45
View File
@@ -3504,6 +3504,51 @@ class TestChannelService:
"app_token": "xapp-ui",
}
def test_start_retries_configured_channel_until_ready(self, monkeypatch):
from app.channels.service import ChannelService
class FlakyReadyChannel(Channel):
starts = 0
def __init__(self, bus, config):
super().__init__(name="slack", bus=bus, config=config)
async def start(self):
type(self).starts += 1
self._running = type(self).starts >= 2
async def stop(self):
self._running = False
async def send(self, msg):
return None
monkeypatch.setattr(
"deerflow.reflection.resolve_class",
lambda import_path, base_class=None: FlakyReadyChannel,
)
async def go():
service = ChannelService(
channels_config={
"slack": {
"enabled": True,
"bot_token": "xoxb-ui",
"app_token": "xapp-ui",
},
}
)
try:
await service.start()
assert FlakyReadyChannel.starts == 2
assert service.get_status()["channels"]["slack"]["running"] is True
finally:
await service.stop()
_run(go())
def test_connection_repo_is_forwarded_to_manager(self):
from app.channels.service import ChannelService