# scopes.core.actor import asyncio from collections.abc import Awaitable, Callable from typing import Any, Optional from scopes.util import keywords as k, Symbol k('full quit') type Behavior = Callable[[Any], Awaitable[Behavior | None]] type Mailbox = asyncio.Queue async def loop(q: asyncio.Queue, bhv: Behavior) -> None: while True: msg = await q.get() if msg is k.quit: break bhv = await bhv(msg) or bhv q.task_done() def create(bhv: Behavior, maxsize: int = 0, group: Optional[asyncio.TaskGroup] = None) -> asyncio.Queue: q: asyncio.Queue = asyncio.Queue(maxsize) if group is None: asyncio.create_task(loop(q, bhv)) else: group.create_task(loop(q, bhv)) return q async def try_send(rcvr: Mailbox, msg: Any) -> Symbol | None: if rcvr.full(): return k.full await rcvr.put(msg) return None