├── AsyncPython.pptx ├── LICENSE ├── README.md ├── client1.py ├── client2.py ├── client3.py ├── client4.py ├── client5.py ├── client6.py ├── client7.py └── server.py /AsyncPython.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fantomius/AsyncPython/a25bbb4ec5d08ac7f6d226d7aa8f8a390d20752b/AsyncPython.pptx -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alexey Kuzmin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AsyncPython 2 | Materials for Moscow Python Meetup 2018 3 | -------------------------------------------------------------------------------- /client1.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | def make_request(): 5 | start_time = time.time() 6 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | sock.connect(('localhost', 8000)) 8 | sock.send(b'GET /\n\n') 9 | resp = sock.recv(100) 10 | sock.close() 11 | end_time = time.time() 12 | print(end_time-start_time) 13 | 14 | while True: 15 | make_request() 16 | -------------------------------------------------------------------------------- /client2.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | from threading import Thread 4 | 5 | def make_request(): 6 | start_time = time.time() 7 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | sock.connect(('localhost', 8000)) 9 | sock.send(b'GET /\n\n') 10 | resp = sock.recv(100) 11 | sock.close() 12 | end_time = time.time() 13 | print(time.strftime("%H:%M:%S"), end_time-start_time) 14 | 15 | from threading import Thread 16 | 17 | def do_request_forever(): 18 | while True: 19 | make_request() 20 | 21 | t1 = Thread(target=do_request_forever) 22 | t2 = Thread(target=do_request_forever) 23 | 24 | t1.start() 25 | t2.start() 26 | -------------------------------------------------------------------------------- /client3.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | from select import select 4 | 5 | from collections import deque 6 | 7 | tasks = deque() 8 | stopped = {} 9 | 10 | def run_queries(): 11 | while any([tasks, stopped]): 12 | while not tasks: 13 | ready_to_read, _, _ = select(stopped.keys(), [], []) 14 | for r in ready_to_read: 15 | tasks.append(stopped.pop(r)) 16 | while tasks: 17 | task = tasks.popleft() 18 | try: 19 | sock = next(task) 20 | stopped[sock] = task 21 | except StopIteration: 22 | print("query done") 23 | 24 | def make_request(): 25 | start_time = time.time() 26 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 27 | sock.connect(('localhost', 8000)) 28 | sock.send(b'GET /\n\n') 29 | 30 | yield sock 31 | 32 | resp = sock.recv(100) 33 | sock.close() 34 | end_time = time.time() 35 | print(end_time-start_time) 36 | 37 | tasks.append(make_request()) 38 | run_queries() -------------------------------------------------------------------------------- /client4.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | from select import select 4 | from threading import Thread 5 | 6 | from collections import deque 7 | 8 | tasks = deque() 9 | stopped = {} 10 | 11 | def run_queries(): 12 | while any([tasks, stopped]): 13 | while not tasks: 14 | ready_to_read, _, _ = select(stopped.keys(), [], []) 15 | for r in ready_to_read: 16 | tasks.append(stopped.pop(r)) 17 | while tasks: 18 | task = tasks.popleft() 19 | try: 20 | sock = next(task) 21 | stopped[sock] = task 22 | except StopIteration: 23 | print("query done") 24 | 25 | def make_request(): 26 | start_time = time.time() 27 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | sock.connect(('localhost', 8000)) 29 | sock.send(b'GET /\n\n') 30 | 31 | yield sock 32 | 33 | resp = sock.recv(100) 34 | sock.close() 35 | end_time = time.time() 36 | print(time.strftime("%H:%M:%S"), end_time-start_time) 37 | 38 | def run_request_producer(): 39 | while True: 40 | tasks.append(make_request()) 41 | time.sleep(1.0) 42 | 43 | t = Thread(target=run_request_producer) 44 | t.start() 45 | 46 | run_queries() 47 | -------------------------------------------------------------------------------- /client5.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | from select import select 4 | from threading import Thread 5 | 6 | from collections import deque 7 | 8 | tasks = deque() 9 | stopped = {} 10 | 11 | def run_queries(): 12 | while any([tasks, stopped]): 13 | while not tasks: 14 | ready_to_read, _, _ = select(stopped.keys(), [], []) 15 | for r in ready_to_read: 16 | tasks.append(stopped.pop(r)) 17 | while tasks: 18 | task = tasks.popleft() 19 | try: 20 | sock = next(task) 21 | stopped[sock] = task 22 | except StopIteration: 23 | print("query done") 24 | 25 | def make_request(): 26 | start_time = time.time() 27 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | sock.connect(('localhost', 8000)) 29 | sock.send(b'GET /\n\n') 30 | 31 | yield sock 32 | 33 | resp = sock.recv(100) 34 | sock.close() 35 | end_time = time.time() 36 | print(time.strftime("%H:%M:%S"), end_time-start_time) 37 | 38 | future_notify, future_event = socket.socketpair() 39 | 40 | def future_done(): 41 | tasks.append(make_request()) 42 | future_notify.send(b'done') 43 | 44 | def future_monitor(): 45 | while True: 46 | yield future_event 47 | future_event.recv(100) 48 | 49 | tasks.append(future_monitor()) 50 | 51 | def run_request_producer(): 52 | while True: 53 | time.sleep(1.0) 54 | future_done() 55 | 56 | t = Thread(target=run_request_producer) 57 | t.start() 58 | 59 | run_queries() 60 | -------------------------------------------------------------------------------- /client6.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | from select import select 4 | from threading import Thread 5 | from collections import deque 6 | 7 | class EventLoop: 8 | def __init__(self): 9 | self.tasks = deque() 10 | self.stopped = {} 11 | 12 | def add_task(self, task): 13 | self.tasks.append(task) 14 | 15 | def add_future(self, future): 16 | self.tasks.append(future.monitor()) 17 | 18 | def run_forever(self): 19 | while any([self.tasks, self.stopped]): 20 | while not self.tasks: 21 | ready_to_read, _, _ = select(self.stopped.keys(), [], [], 1.0) 22 | for r in ready_to_read: 23 | self.tasks.append(self.stopped.pop(r)) 24 | while self.tasks: 25 | task = self.tasks.popleft() 26 | try: 27 | sock = next(task) 28 | self.stopped[sock] = task 29 | except StopIteration: 30 | pass 31 | 32 | class AsyncSocket(socket.socket): 33 | def AsyncRead(self, capacity=100): 34 | yield self 35 | return self.recv(100) 36 | 37 | class Future: 38 | def __init__(self, done_callback): 39 | self.notify, self.event = socket.socketpair() 40 | self.done_callback = done_callback 41 | self.result = None 42 | 43 | def set_done(self, result): 44 | self.result = result 45 | self.notify.send(b'done') 46 | self.done_callback(self.result) 47 | 48 | def monitor(self): 49 | yield self.event 50 | self.event.recv(100) 51 | 52 | 53 | def make_request(): 54 | start_time = time.time() 55 | sock = AsyncSocket(socket.AF_INET, socket.SOCK_STREAM) 56 | sock.connect(('localhost', 8000)) 57 | sock.send(b'GET /\n\n') 58 | resp = yield from sock.AsyncRead(100) 59 | sock.close() 60 | end_time = time.time() 61 | print(time.strftime("%H:%M:%S"), end_time-start_time) 62 | 63 | ev = EventLoop() 64 | 65 | def future_producer(): 66 | while True: 67 | f = Future(lambda x: ev.add_task(make_request())) 68 | ev.add_future(f) 69 | time.sleep(1.0) 70 | f.set_done(1.0) 71 | 72 | t = Thread(target=future_producer) 73 | t.start() 74 | 75 | ev.run_forever() 76 | 77 | 78 | -------------------------------------------------------------------------------- /client7.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import aiohttp 3 | import time 4 | 5 | ev = asyncio.get_event_loop() 6 | 7 | async def make_request(): 8 | async with aiohttp.ClientSession() as session: 9 | async with session.get('http://localhost:8000/') as resp: 10 | print(time.strftime("%H:%M:%S"), await resp.text()) 11 | 12 | async def request_producer(): 13 | while True: 14 | ev.create_task(make_request()) 15 | await asyncio.sleep(1.0) 16 | 17 | ev.create_task(request_producer()) 18 | ev.run_forever() -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | 2 | from sanic import Sanic 3 | from sanic.response import text 4 | from asyncio import sleep 5 | 6 | app = Sanic() 7 | 8 | @app.route('/') 9 | async def test(request): 10 | await sleep(5) 11 | return text("Hello") 12 | 13 | if __name__ == '__main__': 14 | app.run(host='0.0.0.0', port=8000, workers=1) 15 | --------------------------------------------------------------------------------