Skip to content

Instantly share code, notes, and snippets.

@Corwinpro
Created January 10, 2021 12:08
Show Gist options
  • Save Corwinpro/bcc2a93bb583a87d7479c1e651d15ff0 to your computer and use it in GitHub Desktop.
Save Corwinpro/bcc2a93bb583a87d7479c1e651d15ff0 to your computer and use it in GitHub Desktop.
A simple asyncio code that emulates a Post Office
import asyncio
import time
import random
from collections import defaultdict
NOF_AGENTS = 20
NOF_RECIPIENTS = 3
class Message:
count = 0
def __init__(self, source, content):
self.source = source
self.content = content
Message.count += 1
class Post:
def __init__(self):
self.mailbox = defaultdict(list)
def get_messages(self, agent_id):
pending_messages = self.mailbox[agent_id]
self.mailbox[agent_id] = []
return pending_messages
def send_message(self, recipient, message):
self.mailbox[recipient].append(message)
post = Post()
class Agent:
id = 1
received_messages = 0
idle_time = 0.0
def __init__(self):
self.id = Agent.id
Agent.id += 1
self.messages = []
def store_messages(self, messages):
self.messages.extend(messages)
Agent.received_messages += len(messages)
def create_message(self):
return Message(source=self.id, content=time.ctime())
async def sleep(self):
sleep_time = random.random() * 10.0
await asyncio.sleep(sleep_time)
Agent.idle_time += sleep_time
async def cycle(self):
while True:
await self.sleep()
new_messages = post.get_messages(agent_id=self.id)
self.store_messages(new_messages)
recipients = random.sample(range(1, NOF_AGENTS), NOF_RECIPIENTS)
for agent_recipient in recipients:
if agent_recipient != self.id:
post.send_message(
recipient=agent_recipient,
message=self.create_message()
)
if new_messages:
messages_str = f"{[message.source for message in new_messages]}"
else:
messages_str = "no"
print(
f"Agent {self.id} sent messages to agents {recipients}, "
f"got messages from {messages_str} agents "
)
async def main():
tasks = [Agent().cycle() for _ in range(NOF_AGENTS)]
group = asyncio.gather(*tasks, return_exceptions=True)
await group
if __name__ == "__main__":
try:
asyncio.run(main())
finally:
print(
f"Sent {Message.count} messages, "
f"received {Agent.received_messages}, and "
f"{sum(len(agents_post) for agents_post in post.mailbox.values())}""
" not delivered.""
)
print(f"Agents were sleeping for {Agent.idle_time} sec.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment