Skip to content

FirstOf

Source and Output

"""Example: FirstOf races two events and reacts to whichever arrives first."""

from asimpy import Environment, FirstOf, Process, Queue
from _util import example

SERVICE_TIME = 5  # ticks before the server delivers a result
PATIENCE = 3  # ticks a client is willing to wait before leaving


class Server(Process):
    def init(self, queue):
        self._queue = queue

    async def run(self):
        await self.timeout(SERVICE_TIME)
        self._env.log("server", "deliver result")
        await self._queue.put("result")


class Client(Process):
    def init(self, queue):
        self._queue = queue

    async def run(self):
        self._env.log("client", "waiting")
        key, value = await FirstOf(
            self._env,
            served=self._queue.get(),
            timeout=self.timeout(PATIENCE),
        )
        if key == "served":
            self._env.log("client", f"received {value}")
        else:
            self._env.log("client", "timed out, leaving")


def main():
    env = Environment()
    queue = Queue(env)
    Server(env, queue)
    Client(env, queue)
    env.run()
    return env


if __name__ == "__main__":
    example(main)

time name event
0 client waiting
3 client timed out, leaving
5 server deliver result

Key Points

  1. FirstOf(env, **events) triggers when the first named child event fires. Its value is a (key, value) tuple identifying the winner. All non-winning events are cancelled.

  2. Because PATIENCE=3 < SERVICE_TIME=5, the timeout wins and the client logs "timed out, leaving" at t=3, before the server delivers at t=5.

  3. Cancelling queue.get() puts the slot back so the queue is not silently consumed. The server still puts its result at t=5, but no consumer retrieves it so the simulation ends there.

Check for Understanding

If you set PATIENCE = 5, which branch in the client's if statement runs? How does the output change, and why does the server's log entry disappear?