rapidity 0.0.5.88265 → 0.0.5.88564

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: 6faa9172962dc6c7004e59dc8e827f16572b99c41b586c7221539d2bf253dda5
4
- data.tar.gz: fb698e043084b6ad4491c2c85b785f9678aba9996f333e3df6bae45d6f76a76a
3
+ metadata.gz: dc0bdcbad063ffce0142d3eacdad37e4ee78186ee4bb2092c1677c871fb52fa2
4
+ data.tar.gz: 15017d1bae8b36afc44d484616bc2fe5f21c85e868606c9dc137ad0f4c04a5f1
5
5
  SHA512:
6
- metadata.gz: d76e69e666ae0ab3a541f8ce725b2aae485ac9c7218163bd23bcaf4023f33db748da42f5dab7b978699f3f0ac3c0cfce9b49e2933127b81613d7df4533bc7496
7
- data.tar.gz: 7434ad4f51dc20142d28f5df0bd004f79e8674dec8ac317683d18921626469525f81956ce4c3b7a8260c11cdb3cd7f281bb3f7f7aac5123e532899a9446d1587
6
+ metadata.gz: 68967c5c216162141ddf9be4871c47f4db4966b07ad2e2faac5950ec1987244a445df52e41693b3fcb6a324d7d61b640c1293b139d671059047e84778a5df3b0
7
+ data.tar.gz: a97d793eb5b42c556ee971c1484f25b5910f8576ba280bd60ce845780f79cd63fdd015a5618568b04b4e9bda83000995e3dda096d920d7aca3c33e8ef5a7c129
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rapidity (0.0.5.88265)
4
+ rapidity (0.0.5.88564)
5
5
  activesupport
6
6
  connection_pool
7
7
  redis
@@ -0,0 +1,37 @@
1
+ -- args: key, treshold, interval, count
2
+ -- returns: obtained count.
3
+
4
+ -- make some nicer looking variable names:
5
+ local retval = nil
6
+
7
+ -- Redis documentation recommends passing the keys separately so that Redis
8
+ -- can - in the future - verify that they live on the same shard of a cluster, and
9
+ -- raise an error if they are not. As far as can be understood this functionality is not
10
+ -- yet present, but if we can make a little effort to make ourselves more future proof
11
+ -- we should.
12
+ local key = KEYS[1]
13
+ local treshold = tonumber(ARGV[1])
14
+ local interval = tonumber(ARGV[2])
15
+ local count = tonumber(ARGV[3])
16
+
17
+ local current = 0
18
+ local to_return = 0
19
+
20
+ redis.call("SET", key, treshold, "EX", interval, "NX")
21
+ current = redis.call("DECRBY", key, count)
22
+
23
+ -- If we became below zero we must return some value back
24
+ if current < 0 then
25
+ to_return = math.min(count, math.abs(current))
26
+
27
+ -- set 0 to current counter value
28
+ redis.call("SET", key, 0, 'KEEPTTL')
29
+
30
+ -- return obtained part of requested count
31
+ retval = count - to_return
32
+ else
33
+ -- return full of requested count
34
+ retval = count
35
+ end
36
+
37
+ return retval
@@ -6,6 +6,7 @@ module Rapidity
6
6
 
7
7
  attr_reader :pool, :name, :interval, :threshold, :namespace
8
8
 
9
+ LUA_SCRIPT_CODE = File.read(File.join(__dir__, 'limiter.lua'))
9
10
 
10
11
  # Convert message to given class
11
12
  # @params pool - inititalized Redis pool
@@ -30,12 +31,12 @@ module Rapidity
30
31
  # @return remaining counter value
31
32
  def remains
32
33
  results = @pool.with do |conn|
33
- conn.multi do
34
- conn.set(key('remains'), threshold, ex: interval, nx: true)
35
- conn.get(key('remains'))
34
+ conn.multi do |pipeline|
35
+ pipeline.set(key('remains'), threshold, ex: interval, nx: true)
36
+ pipeline.get(key('remains'))
36
37
  end
37
38
  end
38
- results[1].to_i #=> conn.get(key('remains'))
39
+ results[1].to_i #=> pipeline.get(key('remains'))
39
40
  end
40
41
 
41
42
  # Obtain values from counter
@@ -43,38 +44,41 @@ module Rapidity
43
44
  def obtain(count = 5)
44
45
  count = count.abs
45
46
 
46
- results = @pool.with do |conn|
47
- conn.multi do
48
- conn.set(key('remains'), threshold, ex: interval, nx: true)
49
- conn.decrby(key('remains'), count)
47
+ result = begin
48
+ @pool.with do |conn|
49
+ conn.evalsha(@script, keys: [key('remains')], argv: [threshold, interval, count])
50
+ end
51
+ rescue Redis::CommandError => e
52
+ if e.message.include?('NOSCRIPT')
53
+ # The Redis server has never seen this script before. Needs to run only once in the entire lifetime
54
+ # of the Redis server, until the script changes - in which case it will be loaded under a different SHA
55
+ ensure_script_loaded
56
+ retry
57
+ else
58
+ raise e
50
59
  end
51
60
  end
52
61
 
53
- taken = results[1].to_i #=> conn.decrby(key('remains'), count)
62
+ taken = result.to_i
54
63
 
55
- if taken < 0
56
- overflow = taken.abs
57
- to_return = [count, overflow].min
58
-
59
- results = @pool.with do |conn|
60
- conn.multi do
61
- conn.set(key('remains'), threshold - to_return, ex: interval, nx: true)
62
- conn.incrby(key('remains'), to_return)
63
- conn.ttl(key('remains'))
64
- end
64
+ if taken == 0
65
+ ttl = @pool.with do |conn|
66
+ conn.ttl(key('remains'))
65
67
  end
66
68
 
67
- ttl = results[2].to_i #=> conn.ttl(key('remains'))
68
-
69
- # reset if no ttl present
70
- if ttl == -1
69
+ # UNKNOWN BUG? reset if no ttl present. Many years ago once upon time we meet our key without TTL
70
+ if ttl == -1
71
71
  STDERR.puts "ERROR[#{Time.now}]: TTL for key #{key('remains').inspect} disappeared!"
72
- @pool.with {|c| c.expire(key('remains'), interval) }
72
+ @pool.with {|c| c.expire(key('remains'), interval) }
73
73
  end
74
+ end
75
+
76
+ taken
77
+ end
74
78
 
75
- count - to_return
76
- else
77
- count
79
+ def ensure_script_loaded
80
+ @script = @pool.with do |conn|
81
+ conn.script(:load, LUA_SCRIPT_CODE)
78
82
  end
79
83
  end
80
84
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapidity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5.88265
4
+ version: 0.0.5.88564
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yurusov Vlad
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-06-25 00:00:00.000000000 Z
12
+ date: 2022-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -235,6 +235,7 @@ files:
235
235
  - README.md
236
236
  - lib/rapidity.rb
237
237
  - lib/rapidity/composer.rb
238
+ - lib/rapidity/limiter.lua
238
239
  - lib/rapidity/limiter.rb
239
240
  - lib/rapidity/version.rb
240
241
  homepage: