Skip to content

Instantly share code, notes, and snippets.

@toolittlecakes
Created April 21, 2024 09:22
Show Gist options
  • Save toolittlecakes/fbdb3f6c65a90d783145b2fdd6696a89 to your computer and use it in GitHub Desktop.
Save toolittlecakes/fbdb3f6c65a90d783145b2fdd6696a89 to your computer and use it in GitHub Desktop.
Simple implementation showing the idea of async code. Doesn't use async/await keywords or real event_loop for the sake of simplicity and clarity
import time
from collections import deque
from pprint import pprint
START_TIME = time.time()
def run(func):
gen = func()
while True:
try:
next(gen)
except StopIteration as e:
return e.value
def gather(*tasks):
results = [None] * len(tasks)
working_tasks = deque(enumerate(tasks))
while working_tasks:
idx, task = working_tasks.popleft()
try:
next(task)
working_tasks.append((idx, task))
except StopIteration as e:
results[idx] = e.value
yield
return results
def timer(seconds):
start = time.time()
while time.time() - start < seconds:
yield
def async_request(name, delay: float):
print(f"Request {name} started: {time.time() - START_TIME:.2f}")
yield from timer(delay)
print(f"Request {name} finished: {time.time() - START_TIME:.2f}")
return f"Response from {name}: {time.time() - START_TIME:.2f}"
def complex_function():
d = yield from async_request("D", 0.5)
e = yield from async_request("E", 1)
f = yield from gather(async_request("F1", 1.4), async_request("F2", 1.6))
return [d, e, f]
def main():
results = yield from gather(
async_request("A", 3),
async_request("B", 2),
async_request("C", 1),
complex_function(),
)
print("----------------")
print("Results:")
pprint(results)
if __name__ == "__main__":
run(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment