async def kafka_handler(request: web.Request) -> web.StreamResponse: gateway_chan: ac.Chan = request.app['gateway_chan'] response_chan = ac.Chan() logging.info("Kafka request received") await gateway_chan.put( ("no message for the moment".encode('utf8'), response_chan)) return web.Response(text=await response_chan.get())
async def websocket_handler(request: web.Request) -> web.StreamResponse: salutate_chan: ac.Chan = request.app['salutate_chan'] salutation_chan = ac.Chan() response = web.WebSocketResponse() await response.prepare(request) ac.go(websocket_send_from_chan(salutation_chan, response)) while True: msg = await response.receive() if msg.type not in (aiohttp.WSMsgType.TEXT, aiohttp.WSMsgType.BINARY): break print(f"Message received: {MSG_TYPE_NAMES[msg.type]}") await salutate_chan.put(salutation_chan) if msg.type == aiohttp.WSMsgType.ERROR: print('ws connection closed with exception %s' % response.exception()) print(f"Connection ended with message {MSG_TYPE_NAMES[msg.type]}") salutation_chan.close() return response
async def main(): c = ac.Chan() prod = ac.go(producer(c)) cons = ac.go(consumer(c)) await asyncio.sleep(0.6) print('It is late, let us call it a day.') c.close() await asyncio.wait({prod, cons})
async def main(host: str = '0.0.0.0', port: int = 8080) -> None: loop = asyncio.get_running_loop() main_task = asyncio.current_task(loop) signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT) def signal_handler(s): asyncio.create_task(shutdown(s, loop, main_task)) for s in signals: loop.add_signal_handler( s, lambda s=s, loop=loop, main_task=main_task: asyncio.create_task( shutdown(s, loop, main_task))) app = create_app() salutate_chan = ac.Chan() salutate_task = ac.go(salutate_the_world(salutate_chan)) app['salutate_chan'] = salutate_chan gateway_chan = ac.Chan() gateway_task = ac.go(kafka_gateway(gateway_chan)) app['gateway_chan'] = gateway_chan runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, host, port) await site.start() logging.info(f"Server running on {host}:{port}") # Wait forever. Cancelling this task will finish the application. try: while True: await asyncio.sleep(3600) except asyncio.CancelledError: pass finally: await runner.cleanup() gateway_task.cancel() await asyncio.gather(gateway_task) salutate_chan.close() await asyncio.gather(salutate_task) await terminate_outstanding_tasks()
async def kafka_gateway(request_chan: ac.Chan) -> None: loop = asyncio.get_running_loop() producer = aiokafka.AIOKafkaProducer(loop=loop, bootstrap_servers='kafka:9092') await producer.start() response_chan = ac.Chan() consumer_task = ac.go(consume(response_chan)) pending_responses = {} try: key_seq = 1 while True: result, chan = await ac.select(request_chan, response_chan) if result is None: break key: str msg: str resp_chan: ac.Chan if chan is request_chan: msg, resp_chan = result key = f'msg{key_seq}' key_seq += 1 logging.info(f"Requesting salutation {key}, {msg}") await producer.send_and_wait("salutation-requests", key=key.encode('utf8'), value=msg) logging.info("Message sent") await producer.flush() pending_responses[key] = resp_chan elif chan is response_chan: key_bytes, msg_bytes = result key, msg = key_bytes.decode('utf8'), msg_bytes.decode('utf8') if key in pending_responses: resp_chan = pending_responses[key] del pending_responses[key] await resp_chan.put(msg) else: logging.error(f"Message key '{key}' not awaiting response") except asyncio.CancelledError: logging.info("Gateway cancelled") finally: consumer_task.cancel() await asyncio.gather(consumer_task) logging.info("Stopping producer") await producer.stop()
import aiochan as ac import asyncio c = ac.Chan() async def producer(c): i = 0 while True: await asyncio.sleep(0.1) # producing stuff takes time i += 1 still_open = await c.put('product ' + str(i)) if not still_open: await asyncio.sleep(0.5) print(f'product {i} produced but never delivered, producer goes ' 'home now') break else: print(f"product {i} delivered") async def consumer(c): while True: product = await c.get() if product is not None: print('obtained:', product) else: print('consumer goes home') break
async def salutation_handler(request: web.Request) -> web.StreamResponse: salutate_chan: ac.Chan = request.app['salutate_chan'] salutation_chan = ac.Chan() await salutate_chan.put(salutation_chan) return web.Response(text=await salutation_chan.get())