praroter 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/praroter/filly_bucket/bucket.rb +7 -1
- data/lib/praroter/filly_bucket/creator.rb +2 -2
- data/lib/praroter/filly_bucket/filly_bucket.lua +18 -12
- data/lib/praroter/version.rb +1 -1
- data/scripts/test.sh +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45d402fb542e1179c77ef384e333750f8435f48f6ecc3fc0e9ac1a1e790184b4
|
4
|
+
data.tar.gz: '048682c2d4f5303e264f77ce31f2a8c0e519c829e4508ed308b0f4f7738ca71f'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29965045ee43c7c5f3c1c4e77d7d3c7e8f60acfa61ae441d705a83f1e41fc3523d41385de551fda9060d185a86e53f1f769e5cab82748eec6ccb8a344ee3988c
|
7
|
+
data.tar.gz: 4526e457a81f08204de5ba456e5b2295ae4ee30f9c5dcf77222c8c8b3c536616212c2a71d36aba58be6ff29a331946364f5baba95d5660a68096ca11045b33cf
|
@@ -9,6 +9,10 @@ module Praroter
|
|
9
9
|
@fill_rate = fill_rate
|
10
10
|
@capacity = capacity
|
11
11
|
@creator = creator
|
12
|
+
|
13
|
+
raise ArgumentError, "key must be a string" if @key.class != String
|
14
|
+
raise ArgumentError, "fill_rate must be an integer" if @fill_rate.class != Integer
|
15
|
+
raise ArgumentError, "capacity must be an integer" if @capacity.class != Integer
|
12
16
|
end
|
13
17
|
|
14
18
|
def state
|
@@ -33,7 +37,9 @@ module Praroter
|
|
33
37
|
end
|
34
38
|
|
35
39
|
def drain(amount)
|
36
|
-
raise ArgumentError, "drain amount must be
|
40
|
+
raise ArgumentError, "drain amount must be an integer" if amount.class != Integer
|
41
|
+
raise ArgumentError, "drain amount must be a positive number" if amount < 0
|
42
|
+
|
37
43
|
@creator.run_lua_bucket_script(self, amount)
|
38
44
|
end
|
39
45
|
|
@@ -18,12 +18,12 @@ module Praroter
|
|
18
18
|
begin
|
19
19
|
# The script returns a tuple of "whole tokens, microtokens"
|
20
20
|
# to be able to smuggle the float across (similar to Redis TIME command)
|
21
|
-
new_bucket_level, bucket_capacity, fill_rate = r.evalsha(
|
21
|
+
new_bucket_level, bucket_capacity, fill_rate, scoop = r.evalsha(
|
22
22
|
LUA_SCRIPT_HASH,
|
23
23
|
keys: [bucket.level_key, bucket.last_updated_key],
|
24
24
|
argv: [bucket.capacity, bucket.fill_rate, amount]
|
25
25
|
)
|
26
|
-
BucketState.new(new_bucket_level, bucket_capacity, fill_rate,
|
26
|
+
BucketState.new(new_bucket_level, bucket_capacity, fill_rate, scoop)
|
27
27
|
rescue Redis::CommandError => e
|
28
28
|
if e.message.include? "NOSCRIPT"
|
29
29
|
# The Redis server has never seen this script before. Needs to run only once in the entire lifetime
|
@@ -33,19 +33,25 @@ local new_bucket_level = bucket_level + (fill_rate * dt) - scoop
|
|
33
33
|
-- and _then_ and add the tokens we fillup with
|
34
34
|
new_bucket_level = math.min(bucket_capacity, new_bucket_level)
|
35
35
|
|
36
|
-
-- Compute the key TTL for the bucket. We are interested in how long it takes the bucket
|
37
|
-
-- to leak all the way to bucket_capacity, as this is the time when the values stay relevant. We pad with 1 second
|
38
|
-
-- to have a little cushion.
|
39
|
-
local key_lifetime = nil
|
40
|
-
if new_bucket_level < 0 then -- if new_bucket_level is negative, then the TTL need to be longer
|
41
|
-
key_lifetime = math.ceil((math.abs(bucket_capacity - new_bucket_level) / fill_rate) + 1)
|
42
|
-
else
|
43
|
-
key_lifetime = math.ceil((bucket_capacity / fill_rate) + 1)
|
44
|
-
end
|
45
|
-
|
46
36
|
if new_bucket_level == bucket_capacity then
|
47
|
-
|
37
|
+
-- We subtract new_bucket_level with scoop to maintain expectations
|
38
|
+
-- there are cases where (bucket_level + (fill_rate * dt) - scoop) will be higher than
|
39
|
+
-- new_bucket_level, and in those cases consumers will expect to see:
|
40
|
+
-- {9995, 10000, 250, 5}
|
41
|
+
-- instead of:
|
42
|
+
-- {10000, 10000, 250, 5}
|
43
|
+
return {new_bucket_level - scoop, bucket_capacity, fill_rate, scoop}
|
48
44
|
else
|
45
|
+
-- Compute the key TTL for the bucket. We are interested in how long it takes the bucket
|
46
|
+
-- to leak all the way to bucket_capacity, as this is the time when the values stay relevant. We pad with 1 second
|
47
|
+
-- to have a little cushion.
|
48
|
+
local key_lifetime = nil
|
49
|
+
if new_bucket_level < 0 then -- if new_bucket_level is negative, then the TTL need to be longer
|
50
|
+
key_lifetime = math.ceil((math.abs(bucket_capacity - new_bucket_level) / fill_rate) + 1)
|
51
|
+
else
|
52
|
+
key_lifetime = math.ceil((bucket_capacity / fill_rate) + 1)
|
53
|
+
end
|
54
|
+
|
49
55
|
-- Save the new bucket level
|
50
56
|
redis.call("SETEX", bucket_level_key, key_lifetime, new_bucket_level)
|
51
57
|
|
@@ -53,5 +59,5 @@ else
|
|
53
59
|
-- can be correctly determined on the next invocation
|
54
60
|
redis.call("SETEX", last_updated_key, key_lifetime, now)
|
55
61
|
|
56
|
-
return {new_bucket_level, bucket_capacity, fill_rate}
|
62
|
+
return {new_bucket_level, bucket_capacity, fill_rate, scoop}
|
57
63
|
end
|
data/lib/praroter/version.rb
CHANGED
data/scripts/test.sh
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
#!/bin/bash
|
2
|
-
redis-cli --ldb --eval lib/praroter/filly_bucket.lua filly_bucket.api.
|
2
|
+
redis-cli --ldb --eval lib/praroter/filly_bucket/filly_bucket.lua filly_bucket.api.user_42.bucket_level filly_bucket.api.user_42.last_updated , 10000 250 1000
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: praroter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Grubbe
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|