You've already forked request-coalescing-py
mirror of
https://github.com/hexolan/request-coalescing-py.git
synced 2026-03-26 10:11:16 +00:00
initial commit
This commit is contained in:
33
request_coalescing_py/coalescer.py
Normal file
33
request_coalescing_py/coalescer.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
|
||||
from request_coalescing_py.models import Item
|
||||
from request_coalescing_py.database import DatabaseRepo
|
||||
|
||||
|
||||
class CoalescingRepo:
|
||||
def __init__(self, repo: DatabaseRepo):
|
||||
self._repo = repo
|
||||
|
||||
self._queue = asyncio.Queue()
|
||||
self._queued = {} # map of item_id: future
|
||||
|
||||
async def get_by_id(self, item_id: int) -> "asyncio.Future[Optional[Item]]":
|
||||
# Check if there is an already pending request for that item.
|
||||
fut = self._queued.get(item_id)
|
||||
if fut:
|
||||
return fut
|
||||
|
||||
# There is not a pending request.
|
||||
fut = asyncio.get_event_loop().create_future()
|
||||
self._queued[item_id] = fut
|
||||
await self._queue.put(item_id)
|
||||
return fut
|
||||
|
||||
async def process_queue(self) -> None:
|
||||
while True:
|
||||
item_id = await self._queue.get()
|
||||
item = await self._repo.get_by_id(item_id)
|
||||
self._queued[item_id].set_result(item)
|
||||
del self._queued[item_id]
|
||||
self._queue.task_done()
|
||||
Reference in New Issue
Block a user