diff --git a/scopes/core/actor.py b/scopes/core/actor.py index 4863b0a..b2787f6 100644 --- a/scopes/core/actor.py +++ b/scopes/core/actor.py @@ -4,9 +4,11 @@ import asyncio from collections.abc import Awaitable, Callable from typing import Any, Optional -from scopes.util import keywords as k +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: @@ -14,12 +16,20 @@ async def loop(q: asyncio.Queue, bhv: Behavior) -> None: if msg is k.quit: break bhv = await bhv(msg) or bhv + q.task_done() -def create(bhv: Behavior, group: Optional[asyncio.TaskGroup] = None) -> asyncio.Queue: - q: asyncio.Queue = asyncio.Queue() +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 +