source file: /home/buildslave/tahoe/edgy/build/src/allmydata/util/limiter.py
file stats: 26 lines, 26 executed: 100.0% covered
1. 2. from twisted.internet import defer 3. from foolscap.eventual import eventually 4. 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. 9. """ 10. 11. def __init__(self, limit=10): 12. self.limit = limit 13. self.pending = [] 14. self.active = 0 15. 16. def add(self, cb, *args, **kwargs): 17. d = defer.Deferred() 18. task = (cb, args, kwargs, d) 19. self.pending.append(task) 20. self.maybe_start_task() 21. return d 22. 23. def maybe_start_task(self): 24. if self.active >= self.limit: 25. return 26. if not self.pending: 27. return 28. (cb, args, kwargs, done_d) = self.pending.pop(0) 29. self.active += 1 30. d = defer.maybeDeferred(cb, *args, **kwargs) 31. d.addBoth(self._done, done_d) 32. 33. def _done(self, res, done_d): 34. self.active -= 1 35. eventually(done_d.callback, res) 36. self.maybe_start_task()