gcra 1.0.3 → 1.0.4
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/gcra/redis_store.rb +17 -12
- data/lib/gcra/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4022887c88859ed2259a2e49450a62b1215b73b
|
4
|
+
data.tar.gz: 8e5fe0ed06ca9012b455fb91571fa45d4c0f75ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e175732bc7e3d2f3e2fd0e9c4d75fbcaa80c8ad3786229ffdc22aff210f96d9a66ceacab0788a55eba4abcb0ac876c34d3654d25b8481ee1c28bfa643e62b2b9
|
7
|
+
data.tar.gz: 4407751fe08bb38ad05c0af7fbaba7b9657d55cddd696a90a62a4b7550f1c57c8ddc5f8c94bd63ed78c6cfb405e51ea96a33dd9b8dba63b42383f77a8032bd51
|
data/lib/gcra/redis_store.rb
CHANGED
@@ -12,7 +12,11 @@ module GCRA
|
|
12
12
|
redis.call('psetex', KEYS[1], ARGV[3], ARGV[2])
|
13
13
|
return 1
|
14
14
|
EOF
|
15
|
+
|
16
|
+
# Digest::SHA1.hexdigest(CAS_SCRIPT)
|
17
|
+
CAS_SHA = "89118e702230c0d65969c5fc557a6e942a2f4d31".freeze
|
15
18
|
CAS_SCRIPT_MISSING_KEY_RESPONSE = 'key does not exist'.freeze
|
19
|
+
SCRIPT_NOT_IN_CACHE_RESPONSE = 'NOSCRIPT No matching script. Please use EVAL.'
|
16
20
|
|
17
21
|
def initialize(redis, key_prefix)
|
18
22
|
@redis = redis
|
@@ -22,10 +26,12 @@ module GCRA
|
|
22
26
|
# Returns the value of the key or nil, if it isn't in the store.
|
23
27
|
# Also returns the time from the Redis server, with microsecond precision.
|
24
28
|
def get_with_time(key)
|
25
|
-
time_response = @redis.
|
29
|
+
time_response, value = @redis.pipelined do
|
30
|
+
@redis.time # returns tuple (seconds since epoch, microseconds)
|
31
|
+
@redis.get(@key_prefix + key)
|
32
|
+
end
|
26
33
|
# Convert tuple to nanoseconds
|
27
34
|
time = (time_response[0] * 1_000_000 + time_response[1]) * 1_000
|
28
|
-
value = @redis.get(@key_prefix + key)
|
29
35
|
if value != nil
|
30
36
|
value = value.to_i
|
31
37
|
end
|
@@ -34,17 +40,11 @@ module GCRA
|
|
34
40
|
end
|
35
41
|
|
36
42
|
# Set the value of key only if it is not already set. Return whether the value was set.
|
37
|
-
# Also set the key's expiration (ttl, in seconds).
|
43
|
+
# Also set the key's expiration (ttl, in seconds).
|
38
44
|
def set_if_not_exists_with_ttl(key, value, ttl_nano)
|
39
45
|
full_key = @key_prefix + key
|
40
|
-
|
41
|
-
|
42
|
-
if did_set
|
43
|
-
ttl_milli = calculate_ttl_milli(ttl_nano)
|
44
|
-
@redis.pexpire(full_key, ttl_milli)
|
45
|
-
end
|
46
|
-
|
47
|
-
return did_set
|
46
|
+
ttl_milli = calculate_ttl_milli(ttl_nano)
|
47
|
+
@redis.set(full_key, value, nx: true, px: ttl_milli)
|
48
48
|
end
|
49
49
|
|
50
50
|
# Atomically compare the value at key to the old value. If it matches, set it to the new value
|
@@ -52,12 +52,17 @@ module GCRA
|
|
52
52
|
# return false with no error. If the swap succeeds, update the ttl for the key atomically.
|
53
53
|
def compare_and_set_with_ttl(key, old_value, new_value, ttl_nano)
|
54
54
|
full_key = @key_prefix + key
|
55
|
+
retried = false
|
55
56
|
begin
|
56
57
|
ttl_milli = calculate_ttl_milli(ttl_nano)
|
57
|
-
swapped = @redis.
|
58
|
+
swapped = @redis.evalsha(CAS_SHA, keys: [full_key], argv: [old_value, new_value, ttl_milli])
|
58
59
|
rescue Redis::CommandError => e
|
59
60
|
if e.message == CAS_SCRIPT_MISSING_KEY_RESPONSE
|
60
61
|
return false
|
62
|
+
elsif e.message == SCRIPT_NOT_IN_CACHE_RESPONSE && !retried
|
63
|
+
@redis.script('load', CAS_SCRIPT)
|
64
|
+
retried = true
|
65
|
+
retry
|
61
66
|
end
|
62
67
|
raise
|
63
68
|
end
|
data/lib/gcra/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gcra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Frister
|
8
|
+
- Tobias Schoknecht
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2019-02-27 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rspec
|
@@ -40,7 +41,7 @@ dependencies:
|
|
40
41
|
version: '3.3'
|
41
42
|
description: GCRA implementation for rate limiting
|
42
43
|
email:
|
43
|
-
-
|
44
|
+
- tobias.schoknecht@barzahlen.de
|
44
45
|
executables: []
|
45
46
|
extensions: []
|
46
47
|
extra_rdoc_files: []
|
@@ -48,7 +49,7 @@ files:
|
|
48
49
|
- lib/gcra/rate_limiter.rb
|
49
50
|
- lib/gcra/redis_store.rb
|
50
51
|
- lib/gcra/version.rb
|
51
|
-
homepage: https://github.com/Barzahlen/gcra
|
52
|
+
homepage: https://github.com/Barzahlen/gcra-ruby
|
52
53
|
licenses:
|
53
54
|
- MIT
|
54
55
|
metadata: {}
|