Examples
Timeout
"""Repeated sleeping."""
from asimpy import Environment, Process
class Sleeper(Process):
async def run(self):
print(f"{self.now:>4}: starts")
for i in range(3):
print(f"{self.now:>4}")
await self.timeout(5)
print(f"{self.now:>4}: finishes")
env = Environment()
Sleeper(env)
env.run()
0: starts
0
5
10
15: finishes
Barrier
"""Simulate people waiting on shared resource."""
from asimpy import Environment, Process, Barrier
class Waiter(Process):
def init(self, name: str, barrier: Barrier):
self.name = name
self.barrier = barrier
async def run(self):
print(f"{self.now:>4}: {self.name} arrives")
await self.barrier.wait()
print(f"{self.now:>4}: {self.name} leaves")
class Releaser(Process):
def init(self, name: str, barrier: Barrier):
self.name = name
self.barrier = barrier
async def run(self):
print(f"{self.now:>4}: {self.name} starts")
await self.timeout(2)
await self.barrier.release()
print(f"{self.now:>4}: {self.name} finishes")
env = Environment()
barrier = Barrier(env)
Waiter(env, "Alice", barrier)
Waiter(env, "Bob", barrier)
Waiter(env, "Charlie", barrier)
Releaser(env, "Zemu", barrier)
env.run()
0: Alice arrives
0: Bob arrives
0: Charlie arrives
0: Zemu starts
2: Zemu finishes
2: Alice leaves
2: Bob leaves
2: Charlie leaves
Shared Resource
"""Simulate people waiting on shared resource."""
from asimpy import Environment, Process, Resource
class Customer(Process):
def init(self, name: str, counter: Resource):
self.name = name
self.counter = counter
async def run(self):
print(f"{self.now:>4}: {self.name} arrives")
async with self.counter:
print(f"{self.now:>4}: {self.name} starts service")
await self.timeout(5)
print(f"{self.now:>4}: {self.name} leaves")
env = Environment()
counter = Resource(env, capacity=2)
Customer(env, "Alice", counter)
Customer(env, "Bob", counter)
Customer(env, "Charlie", counter)
env.run()
0: Alice arrives
0: Bob arrives
0: Charlie arrives
0: Alice starts service
0: Bob starts service
5: Alice leaves
5: Charlie starts service
5: Bob leaves
10: Charlie leaves
FIFO Queue
"""Testing queueing."""
from asimpy import Environment, Process, Queue
class Producer(Process):
def init(self, queue: Queue):
self.queue = queue
async def run(self):
for i in range(3):
item = f"item-{i}"
print(f"producer putting {item} at {self.now}")
await self.queue.put(item)
print(f"producer sleeping at {self.now}")
await self.timeout(2)
def __str__(self):
return "producer"
class Consumer(Process):
def init(self, queue: Queue):
self.queue = queue
async def run(self):
for i in range(3):
print(f"consumer waiting for {i} at {self.now}")
item = await self.queue.get()
print(f"consumer got {item} at {self.now}")
def __str__(self):
return "consumer"
env = Environment()
queue = Queue(env)
Producer(env, queue)
Consumer(env, queue)
env.run()
producer putting item-0 at 0
producer sleeping at 0
consumer waiting for 0 at 0
consumer got item-0 at 0
consumer waiting for 1 at 0
producer putting item-1 at 2
producer sleeping at 2
consumer got item-1 at 2
consumer waiting for 2 at 2
producer putting item-2 at 4
producer sleeping at 4
consumer got item-2 at 4
Priority Queue
"""Testing queueing."""
from asimpy import Environment, Process, PriorityQueue
class Producer(Process):
def init(self, queue: PriorityQueue):
self.queue = queue
async def run(self):
for i in range(3, 0, -1):
print(f"producer putting {i} at {self.now}")
await self.queue.put(i)
class Consumer(Process):
def init(self, queue: PriorityQueue):
self.queue = queue
async def run(self):
await self.timeout(1)
for i in range(3):
item = await self.queue.get()
print(f"consumer got {item}")
env = Environment()
queue = PriorityQueue(env)
Producer(env, queue)
Consumer(env, queue)
env.run()
producer putting 3 at 0
producer putting 2 at 0
producer putting 1 at 0
consumer got 1
consumer got 2
consumer got 3
Interrupts
"""Simulate interrupts."""
from asimpy import Environment, Interrupt, Process
class Actor(Process):
async def run(self):
print(f"{self.now:>4}: actor start")
for i in range(4):
try:
print(f"{self.now:>4}/{i}: actor about to sleep")
await self.timeout(2)
print(f"{self.now:>4}/{i}: actor wakes with {self._interrupt}")
except Interrupt as exc:
print(f"{self.now:>4}/{i}: actor interrupted with {exc.cause}")
print(f"{self.now:>4}: actor end")
def __str__(self):
return f"actor+{self._interrupt}"
class Interrupter(Process):
def init(self, other: Process):
self.other = other
async def run(self):
print(f"{self.now:>4}: interrupter start")
for i in range(2):
await self.timeout(3)
print(f"{self.now:>4}/{i}: scheduling interrupt")
self.other.interrupt("message")
print(f"{self.now:>4}: interrupter end")
def __str__(self):
return f"interrupter+{self._interrupt}"
env = Environment()
actor = Actor(env)
Interrupter(env, actor)
env.run()
0: actor start
0/0: actor about to sleep
0: interrupter start
2/0: actor wakes with None
2/1: actor about to sleep
3/0: scheduling interrupt
3/1: actor interrupted with message
3/2: actor about to sleep
4/2: actor wakes with None
4/3: actor about to sleep
5/3: actor wakes with None
5: actor end
6/1: scheduling interrupt
6: interrupter end
AllOf
from asimpy import AllOf, Environment, Process
class Waiter(Process):
async def run(self):
print(f"{self.now:>4}: starts")
await AllOf(self._env, a=self.timeout(5), b=self.timeout(10))
print(f"{self.now:>4}: finishes")
env = Environment()
Waiter(env)
env.run()
FirstOf with Timeout
from asimpy import Environment, Process, FirstOf
class Waiter(Process):
async def run(self):
print(f"{self.now:>4}: starts")
name, value = await FirstOf(
self._env,
a=self.timeout(5),
b=self.timeout(10),
)
print(f"{self.now:>4}: first finished -> {name}")
print(f"{self.now:>4}: finishes")
env = Environment()
Waiter(env)
env.run()
0: starts
5: first finished -> a
5: finishes
FirstOf with Queue
from asimpy import Environment, Process, Queue, FirstOf
class Tester(Process):
def init(self, q1: Queue, q2: Queue):
self.q1 = q1
self.q2 = q2
async def run(self):
item = await FirstOf(
self._env,
a=self.q1.get(),
b=self.q2.get(),
)
print(f"winner got {item}")
# Drain remaining items
if self.q1._items:
print("q1 still has:", self.q1._items)
if self.q2._items:
print("q2 still has:", self.q2._items)
env = Environment()
q1 = Queue(env)
q2 = Queue(env)
env.immediate(lambda: q1._items.append("A"))
env.immediate(lambda: q2._items.append("B"))
Tester(env, q1, q2)
env.run()