Skip to content

Commit 4e03bbd

Browse files
fix: cleanup code is not executed correctly when bot exits (#176)
Co-authored-by: st1020 <[email protected]>
1 parent 06afa44 commit 4e03bbd

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

alicebot/bot.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,18 @@ async def _run(self) -> None:
236236

237237
await self._should_exit.wait()
238238
finally:
239-
for _adapter in self.adapters:
240-
for adapter_shutdown_hook_func in self._adapter_shutdown_hooks:
241-
await adapter_shutdown_hook_func(_adapter)
242-
await _adapter.shutdown()
239+
with anyio.CancelScope(shield=True):
240+
for _adapter in self.adapters:
241+
for adapter_shutdown_hook_func in self._adapter_shutdown_hooks:
242+
await adapter_shutdown_hook_func(_adapter)
243+
await _adapter.shutdown()
243244

244-
for bot_exit_hook_func in self._bot_exit_hooks:
245-
await bot_exit_hook_func(self)
245+
for bot_exit_hook_func in self._bot_exit_hooks:
246+
await bot_exit_hook_func(self)
246247

247-
self.adapters.clear()
248-
self.plugins_priority_dict.clear()
249-
self._module_path_finder.path.clear()
248+
self.adapters.clear()
249+
self.plugins_priority_dict.clear()
250+
self._module_path_finder.path.clear()
250251

251252
def _remove_plugin_by_path(
252253
self, file: Path

tests/test_hook.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
from typing import Any
44

5+
from anyio.lowlevel import checkpoint
56
from fake_adapter import fake_adapter_class_factory, fake_message_event_factor
7+
from pytest_mock import MockerFixture
68

79
from alicebot import Adapter, Bot, Event
810

@@ -51,3 +53,23 @@ async def event_postprocessor_hook(_event: Event[Any]) -> None:
5153
"adapter_shutdown_hook",
5254
"bot_exit_hook",
5355
]
56+
57+
58+
def test_multiple_bot_exit_hook(mocker: MockerFixture) -> None:
59+
bot = Bot()
60+
mock = mocker.AsyncMock()
61+
62+
@bot.bot_exit_hook
63+
async def bot_exit_hook1(_bot: Bot) -> None:
64+
await checkpoint()
65+
await mock()
66+
67+
@bot.bot_exit_hook
68+
async def bot_exit_hook2(_bot: Bot) -> None:
69+
await checkpoint()
70+
await mock()
71+
72+
bot.load_adapters(fake_adapter_class_factory(fake_message_event_factor))
73+
bot.run()
74+
75+
assert mock.call_count == 2

0 commit comments

Comments
 (0)