feat(conversations,jobs): a manual run of the rotation job rotates the master now

This commit is contained in:
hh committed 2026-10-19 13:51:15 +02:00
1 parent 7b36cb2156
commit 8f26263d4a
3 files changed
+25 -4

No files matched your search

+12 -2
View File
@@ -77,9 +77,19 @@ class Rotation:
out.append((master, reason)) out.append((master, reason))
return out return out
async def tick(self, now: datetime | None = None) -> list[Conversation]: async def tick(
self, now: datetime | None = None, *, force: str | None = None
) -> list[Conversation]:
"""Rotate the masters that are due; ``force`` rotates every open master."""
rotated: list[Conversation] = [] rotated: list[Conversation] = []
for master, reason in await self.due(now): if force:
due = [
(m, force)
for m in await self._conversations.find(kind="master", status="open")
]
else:
due = await self.due(now)
for master, reason in due:
new = await self.rotate(master, reason) new = await self.rotate(master, reason)
if new is not None: if new is not None:
rotated.append(new) rotated.append(new)
+2 -2
View File
@@ -118,9 +118,9 @@ class JobRun:
self.job, self.payload, delay=delay, trigger=self.trigger self.job, self.payload, delay=delay, trigger=self.trigger
) )
async def rotate(self) -> list[Conversation]: async def rotate(self, *, force: str | None = None) -> list[Conversation]:
rotation = self.scheduler.rotation rotation = self.scheduler.rotation
return await rotation.tick() if rotation is not None else [] return await rotation.tick(force=force) if rotation is not None else []
def background(self, coro: Coroutine[Any, Any, Any]) -> None: def background(self, coro: Coroutine[Any, Any, Any]) -> None:
self.scheduler.background(coro) self.scheduler.background(coro)
+11
View File
@@ -84,6 +84,17 @@ async def test_rotation_does_not_touch_a_master_mid_turn(world: World) -> None:
await world.settle(conv, 1) await world.settle(conv, 1)
async def test_force_rotates_a_master_that_is_not_due(world: World) -> None:
conv = await world.conversations.create(kind="master", agent="a", origin="test")
rotation = Rotation(world.conversations, POLICY)
assert await rotation.tick() == []
rotated = await rotation.tick(force="manual")
assert len(rotated) == 1
assert rotated[0].external_id != conv.external_id
assert (await world.conversations.get(conv.external_id)).status == "closed"
assert len(await world.conversations.find(kind="master", status="open")) == 1
async def test_rotation_order_handout_close_marks_moves_and_new_day( async def test_rotation_order_handout_close_marks_moves_and_new_day(
world: World, world: World,
) -> None: ) -> None: