initial commit
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
c22dade3d5
21 files changed
+564
No files matched your search
@@ -0,0 +1,26 @@
|
||||
import asyncio,time
|
||||
BASE,MAX,STEP,CALM,CAP=0.5,2.0,0.25,5.0,20
|
||||
class State:
|
||||
__slots__=("slot","interval","last","tasks")
|
||||
def __init__(s):s.slot=0.0;s.interval=BASE;s.last=0.0;s.tasks=set()
|
||||
class Limiter:
|
||||
def __init__(s):s.users={}
|
||||
def admit(s,uid):
|
||||
now=time.monotonic();st=s.users.get(uid)
|
||||
if st is None:st=s.users[uid]=State()
|
||||
if len(st.tasks)>=CAP:return st,None,True
|
||||
if now-st.last>CALM:st.interval=BASE
|
||||
wait=max(0.0,st.slot-now)
|
||||
if wait>0:st.interval=min(MAX,st.interval+STEP)
|
||||
st.slot=max(now,st.slot)+st.interval;st.last=now
|
||||
return st,wait,False
|
||||
def flush(s,st):
|
||||
n=len(st.tasks)
|
||||
for t in list(st.tasks):t.cancel()
|
||||
st.tasks.clear();st.slot=0.0;st.interval=BASE;return n
|
||||
def track(s,uid,st,task):
|
||||
st.tasks.add(task)
|
||||
def done(t):
|
||||
st.tasks.discard(t)
|
||||
if not st.tasks and time.monotonic()-st.last>CALM*2 and s.users.get(uid) is st:s.users.pop(uid,None)
|
||||
task.add_done_callback(done)
|
||||
Reference in new issue
Block a user