fix(gateway): keep Feishu websocket off default executor
This commit is contained in:
@@ -3718,7 +3718,7 @@ class FeishuAdapter(BasePlatformAdapter):
|
|||||||
# thread has an empty context = launch profile. connect() runs inside the profile scope
|
# thread has an empty context = launch profile. connect() runs inside the profile scope
|
||||||
# under multiplex (and the supervisor task inherits it), so snapshot it here.
|
# under multiplex (and the supervisor task inherits it), so snapshot it here.
|
||||||
self._ws_future = loop.run_in_executor(
|
self._ws_future = loop.run_in_executor(
|
||||||
None, contextvars.copy_context().run, _run_official_feishu_ws_client, self._ws_client, self)
|
self._get_sdk_executor(), contextvars.copy_context().run, _run_official_feishu_ws_client, self._ws_client, self)
|
||||||
|
|
||||||
async def _connect_webhook(self) -> None:
|
async def _connect_webhook(self) -> None:
|
||||||
if not FEISHU_WEBHOOK_AVAILABLE:
|
if not FEISHU_WEBHOOK_AVAILABLE:
|
||||||
|
|||||||
@@ -189,18 +189,22 @@ class TestFeishuAdapterMessaging(unittest.TestCase):
|
|||||||
"FEISHU_APP_ID": "cli_app",
|
"FEISHU_APP_ID": "cli_app",
|
||||||
"FEISHU_APP_SECRET": "secret_app",
|
"FEISHU_APP_SECRET": "secret_app",
|
||||||
}, clear=True)
|
}, clear=True)
|
||||||
def test_connect_websocket_sets_channel_ua_tag(self):
|
def test_connect_websocket_sets_channel_ua_tag_and_uses_owned_executor(self):
|
||||||
"""Verify that FeishuWSClient receives extra_ua_tags=["channel"].
|
"""Verify the WebSocket client uses the channel tag and owned executor.
|
||||||
|
|
||||||
Without this UA tag the Feishu server does not push group @mention
|
Without this UA tag the Feishu server does not push group @mention
|
||||||
events over the WebSocket transport. See
|
events over the WebSocket transport. The long-lived client must also
|
||||||
|
stay off asyncio's shared default executor. See
|
||||||
https://github.com/NousResearch/hermes-agent/issues/50656
|
https://github.com/NousResearch/hermes-agent/issues/50656
|
||||||
|
https://github.com/NousResearch/hermes-agent/issues/78318
|
||||||
"""
|
"""
|
||||||
from gateway.config import PlatformConfig
|
from gateway.config import PlatformConfig
|
||||||
from plugins.platforms.feishu.adapter import FeishuAdapter
|
from plugins.platforms.feishu.adapter import FeishuAdapter
|
||||||
|
|
||||||
adapter = FeishuAdapter(PlatformConfig())
|
adapter = FeishuAdapter(PlatformConfig())
|
||||||
ws_client = SimpleNamespace()
|
ws_client = SimpleNamespace()
|
||||||
|
owned_executor = object()
|
||||||
|
submitted_executors = []
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch("plugins.platforms.feishu.adapter.FEISHU_AVAILABLE", True),
|
patch("plugins.platforms.feishu.adapter.FEISHU_AVAILABLE", True),
|
||||||
@@ -214,6 +218,7 @@ class TestFeishuAdapterMessaging(unittest.TestCase):
|
|||||||
patch("plugins.platforms.feishu.adapter.release_scoped_lock"),
|
patch("plugins.platforms.feishu.adapter.release_scoped_lock"),
|
||||||
patch.object(adapter, "_hydrate_bot_identity", new=AsyncMock()),
|
patch.object(adapter, "_hydrate_bot_identity", new=AsyncMock()),
|
||||||
patch.object(adapter, "_build_lark_client", return_value=SimpleNamespace()),
|
patch.object(adapter, "_build_lark_client", return_value=SimpleNamespace()),
|
||||||
|
patch.object(adapter, "_get_sdk_executor", return_value=owned_executor),
|
||||||
):
|
):
|
||||||
_mock_event_dispatcher_builder(mock_handler_class)
|
_mock_event_dispatcher_builder(mock_handler_class)
|
||||||
|
|
||||||
@@ -222,7 +227,8 @@ class TestFeishuAdapterMessaging(unittest.TestCase):
|
|||||||
future.set_result(None)
|
future.set_result(None)
|
||||||
|
|
||||||
class _Loop:
|
class _Loop:
|
||||||
def run_in_executor(self, *_args, **_kwargs):
|
def run_in_executor(self, executor, *_args, **_kwargs):
|
||||||
|
submitted_executors.append(executor)
|
||||||
return future
|
return future
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
return False
|
return False
|
||||||
@@ -243,6 +249,7 @@ class TestFeishuAdapterMessaging(unittest.TestCase):
|
|||||||
"FeishuWSClient must receive extra_ua_tags for group @mention delivery")
|
"FeishuWSClient must receive extra_ua_tags for group @mention delivery")
|
||||||
self.assertEqual(call_kwargs["extra_ua_tags"], ["channel"],
|
self.assertEqual(call_kwargs["extra_ua_tags"], ["channel"],
|
||||||
"extra_ua_tags must be ['channel'] to enable group event routing")
|
"extra_ua_tags must be ['channel'] to enable group event routing")
|
||||||
|
self.assertEqual(submitted_executors, [owned_executor])
|
||||||
|
|
||||||
|
|
||||||
@patch.dict(os.environ, {}, clear=True)
|
@patch.dict(os.environ, {}, clear=True)
|
||||||
@@ -2550,4 +2557,3 @@ class TestChatLockEviction(unittest.TestCase):
|
|||||||
adapter = self._make_adapter()
|
adapter = self._make_adapter()
|
||||||
self.assertIsInstance(adapter._chat_locks, _collections.OrderedDict)
|
self.assertIsInstance(adapter._chat_locks, _collections.OrderedDict)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user