Was sollte man noch verbessern?
Code: Alles auswählen
import time
import threading
import concurrent.futures
import queue
def print2(txt,*args):
txt = str(time.time()) + ": " + txt
print(txt,*args)
class Limiter():
def __init__(self, zeitlimit, calllimit):
self.zeitlimit = zeitlimit
self.calllimit = calllimit # diese zahl an Calls darf innerhalb von zeitlimit sekunden gemacht werden.
self.gemachte_anfragen =[]
self.anfragen = queue.Queue()
self.thread = threading.Thread(target=self.run)
def darfich(self,a):
e = threading.Event()
wartezeit = []
self.anfragen.put((e, wartezeit))
e.wait()
print2("darfich {} sleep {}".format(a,wartezeit[0]))
if wartezeit[0] > 0:
time.sleep(wartezeit[0])
def wann_darfich(self):
jetzt = time.time()
anfragencopy = self.gemachte_anfragen[:] # eine Kopie machen, damit einträge entfernt werden können (gehts auch weniger fehleranfällig?)
for timestamp in anfragencopy:
if timestamp < jetzt - self.zeitlimit:
self.gemachte_anfragen.remove(timestamp) # alle zu alten einträge entfernen.
if len(self.gemachte_anfragen) < self.calllimit:
return jetzt
relevantecalls = self.gemachte_anfragen[-self.calllimit:] # auch zukünftige timestamps muessen beachtet werden
if len(relevantecalls) < self.calllimit:
return jetzt
else: # es wurden soviele wie erlaubt gemacht oder gar mehr, dann warten
return relevantecalls[0] + self.zeitlimit # relevantecalls[0] ist der timestamp des ältesten relevanten calls
def run(self):
count = 0
while True:
count += 1
e, wartezeit = self.anfragen.get() # wartet, bis etwas vorhanden ist ... nur wie beende ich das, wenn ich es nicht mehr brauche?
w = self.wann_darfich() # absoluter ts
self.gemachte_anfragen.append(w)
wartezeit.append(w-time.time())
e.set() # e.wait() in "darfich" beenden
if count>=7: # notmaßnahme damit der thread beendet wird
return
limit = Limiter(5,2)
def test(a):
limit.darfich(a)
print2("test {}".format(a))
return a
if __name__ == '__main__':
limit.thread.start()
pool = concurrent.futures.ThreadPoolExecutor(7)
futures = []
futures.append(pool.submit(test, 1))
futures.append(pool.submit(test, 2))
futures.append(pool.submit(test, 3))
futures.append(pool.submit(test, 4))
futures.append(pool.submit(test, 5))
futures.append(pool.submit(test, 6))
futures.append(pool.submit(test, 7))
concurrent.futures.wait(futures)
print2("Vollständig beendet!")