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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a14e168451294700f7c71bed654256c51bcf6742f186f8201f9aebe7a1a6e3e5
4
- data.tar.gz: 5d1995a758edad1c5f054bf665f101fa85ba00bb34eb729415eaf4a7a5f13c1e
3
+ metadata.gz: 45d402fb542e1179c77ef384e333750f8435f48f6ecc3fc0e9ac1a1e790184b4
4
+ data.tar.gz: '048682c2d4f5303e264f77ce31f2a8c0e519c829e4508ed308b0f4f7738ca71f'
5
5
  SHA512:
6
- metadata.gz: bb3c8fb96ff6f5fdec4fe33eff582ba3db6be91caf2714e28f6ba3b4fb79dccc7dbece841a82de1c2becf507c65124cea12257bbebf7ef856cd4fdf261cef725
7
- data.tar.gz: 4b242a9abeccf2844cdeba9a0c939f5846255db810f7cd14bafaf05eafebbf5e70f6b021d83683ca92be3e8205b796721ee1f2017990288c8a181c71e5cddfa8
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 positive" if amount < 0
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, amount)
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
- return {new_bucket_level, bucket_capacity, fill_rate}
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
@@ -1,3 +1,3 @@
1
1
  module Praroter
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -1,2 +1,2 @@
1
1
  #!/bin/bash
2
- redis-cli --ldb --eval lib/praroter/filly_bucket.lua filly_bucket.api.user:42.bucket_level filly_bucket.api.user:42.last_updated , 5000 100 1000
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.1
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-11-30 00:00:00.000000000 Z
12
+ date: 2020-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis