2 from twisted.internet import defer
3 from foolscap.api import eventually
5 class ConcurrencyLimiter:
6 """I implement a basic concurrency limiter. Add work to it in the form of
7 (callable, args, kwargs) tuples. No more than LIMIT callables will be
8 outstanding at any one time.
11 def __init__(self, limit=10):
17 return "<Limiter with %d/%d/%d>" % (self.active, len(self.pending),
20 def add(self, cb, *args, **kwargs):
22 task = (cb, args, kwargs, d)
23 self.pending.append(task)
24 self.maybe_start_task()
27 def maybe_start_task(self):
28 if self.active >= self.limit:
32 (cb, args, kwargs, done_d) = self.pending.pop(0)
34 d = defer.maybeDeferred(cb, *args, **kwargs)
35 d.addBoth(self._done, done_d)
37 def _done(self, res, done_d):
39 eventually(done_d.callback, res)
40 eventually(self.maybe_start_task)