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
-
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. -
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. -
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?