Skip to content

Instantly share code, notes, and snippets.

@oshinko
Last active June 28, 2017 17:03
Show Gist options
  • Save oshinko/874b613f379ac5132c2ea2356d15566d to your computer and use it in GitHub Desktop.
Save oshinko/874b613f379ac5132c2ea2356d15566d to your computer and use it in GitHub Desktop.
Coroutine Event Loops for UDP in Python 3.
# python3 bots.py localhost 8080 100 4 1
import random
import select
import socket
import sys
import time
from datetime import datetime
eventmask = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR
class Poll:
def __init__(self, socket, timeout):
self.poll = select.poll()
self.poll.register(socket, eventmask)
if timeout > -1:
self.timeout = datetime.now().timestamp() + timeout
else:
self.timeout = -1
def keep(self):
self.success = self.poll.poll(0)
now = datetime.now().timestamp()
if self.success or self.timeout > -1 and self.timeout <= now:
return False
return True
class Wait:
def __init__(self, seconds):
self.until = datetime.now().timestamp() + seconds
def keep(self):
return self.until > datetime.now().timestamp()
class Client:
def __init__(self, host, port, timeout, interval):
self.server = (host, port)
self.timeout = timeout
self.interval = random.uniform(interval / 2, interval)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def run(self):
while True:
self.socket.sendto(b'\x00', self.server)
poll = Poll(self.socket, self.timeout)
yield poll
if poll.success:
message = self.socket.recvfrom(1024) # unused.
else:
print('Timeout.')
yield Wait(self.interval)
if __name__ == "__main__":
host = sys.argv[1]
port = int(sys.argv[2])
concurrent = int(sys.argv[3])
timeout = float(sys.argv[4])
interval = float(sys.argv[5])
coroutines = []
for i in range(concurrent):
generator = Client(host, port, timeout, interval).run()
instruction = next(generator)
coroutines.append([generator, instruction])
while True: # main loop
now = datetime.now().timestamp()
new_coroutines = []
for coroutine in coroutines:
generator = coroutine[0]
instruction = coroutine[1]
if not instruction.keep():
instruction = next(generator)
new_coroutines.append([generator, instruction])
coroutines = new_coroutines
time.sleep(0.001)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment