import asyncio from utils.logger import Logger logger = Logger.get_logger(__name__) class RequestCancellation: """ RequestCancellation middleware handles request canceling * In case of API routes where very frequent/expensive requests are made. """ def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return queue = asyncio.Queue() async def message_poller(sentinel, handler_task): nonlocal queue while True: message = await receive() if message["type"] == "http.disconnect": handler_task.cancel() return sentinel await queue.put(message) sentinel = object() handler_task = asyncio.create_task(self.app(scope, queue.get, send)) asyncio.create_task(message_poller(sentinel, handler_task)) try: return await handler_task except asyncio.CancelledError: logger.info('Task Cancellatation Requested.')