Merge 0.10->trunk
[prosody.git] / util / throttle.lua
1
2 local gettime = require "socket".gettime;
3 local setmetatable = setmetatable;
4 local floor = math.floor;
5
6 local _ENV = nil;
7
8 local throttle = {};
9 local throttle_mt = { __index = throttle };
10
11 function throttle:update()
12         local newt = gettime();
13         local elapsed = newt - self.t;
14         self.t = newt;
15         local balance = floor(self.rate * elapsed) + self.balance;
16         if balance > self.max then
17                 self.balance = self.max;
18         else
19                 self.balance = balance;
20         end
21         return self.balance;
22 end
23
24 function throttle:peek(cost)
25         cost = cost or 1;
26         return self.balance >= cost or self:update() >= cost;
27 end
28
29 function throttle:poll(cost, split)
30         if self:peek(cost) then
31                 self.balance = self.balance - cost;
32                 return true;
33         else
34                 local balance = self.balance;
35                 if split then
36                         self.balance = 0;
37                 end
38                 return false, balance, (cost-balance);
39         end
40 end
41
42 local function create(max, period)
43         return setmetatable({ rate = max / period, max = max, t = 0, balance = max }, throttle_mt);
44 end
45
46 return {
47         create = create;
48 };