# scopes.core.actor import asyncio from collections.abc import Awaitable, Callable from typing import Any, Optional from scopes.util import keywords as k, Symbol # keywords: k('active full ok quit retired suspended') type Behavior = Callable[[Any], Awaitable[Behavior | None]] class Mailbox: def __init__(self, maxsize:int = 0, status: Symbol = k.active): self.queue: asyncio.Queue = asyncio.Queue(maxsize) self.status: Symbol = status 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) -> Mailbox: mb = Mailbox(maxsize) asyncio.create_task(loop(mb.queue, bhv)) return mb async def send(mb: Mailbox, msg: Any, no_wait: bool = False) -> Symbol: if mb.status is k.retired: return k.retired if no_wait and mb.queue.full(): return k.full await mb.queue.put(msg) return k.ok