Skip to content

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()
0: starts
  10: finishes

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()
winner got ('a', 'A')