Examples - asimpy

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')