42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
import asyncio
|
|
import itertools
|
|
import datetime as dt
|
|
|
|
from utils.ratelimits import Bucket
|
|
|
|
|
|
def time_to_slotid(time: dt.datetime) -> int:
|
|
"""
|
|
Return the slotid for the provided time.
|
|
"""
|
|
utctime = time.astimezone(dt.timezone.utc)
|
|
hour = utctime.replace(minute=0, second=0, microsecond=0)
|
|
return int(hour.timestamp())
|
|
|
|
|
|
def slotid_to_utc(sessionid: int) -> dt.datetime:
|
|
"""
|
|
Convert the given slotid (hour EPOCH) into a utc datetime.
|
|
"""
|
|
return dt.datetime.fromtimestamp(sessionid, tz=dt.timezone.utc)
|
|
|
|
|
|
async def batchrun_per_second(awaitables, batchsize):
|
|
"""
|
|
Run provided awaitables concurrently,
|
|
ensuring that no more than `batchsize` are running at once,
|
|
and that no more than `batchsize` are spawned per second.
|
|
|
|
Returns list of returned results or exceptions.
|
|
"""
|
|
bucket = Bucket(batchsize, 1)
|
|
sem = asyncio.Semaphore(batchsize)
|
|
|
|
tasks = []
|
|
for awaitable in awaitables:
|
|
await asyncio.gather(bucket.wait(), sem.acquire())
|
|
bucket.request()
|
|
task = asyncio.create_task(awaitable)
|
|
task.add_done_callback(lambda fut: sem.release())
|
|
return await asyncio.gather(*tasks, return_exceptions=True)
|