gcra 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0398e02c46f08f3f248e36db5d87bc49c2185531
4
- data.tar.gz: 47aee2e95b7267165702aa9350c6b71225b7e8f4
3
+ metadata.gz: a4022887c88859ed2259a2e49450a62b1215b73b
4
+ data.tar.gz: 8e5fe0ed06ca9012b455fb91571fa45d4c0f75ed
5
5
  SHA512:
6
- metadata.gz: 2755f80c4957e77ba5073df77c658263682dbbc92730bb7d4231010cdd379550167cad27a83bf321545c9879a45d7ee992219581e7885eabf1c403774bdbc316
7
- data.tar.gz: eb8b0e85d5141fcdf949b428ff930902286c7267d12dd3ae66a3297b58a211d86db03bb8c73cf104ae39cca9e194af1ba093c82c0e2a7a4a65e12ec37153d908
6
+ metadata.gz: e175732bc7e3d2f3e2fd0e9c4d75fbcaa80c8ad3786229ffdc22aff210f96d9a66ceacab0788a55eba4abcb0ac876c34d3654d25b8481ee1c28bfa643e62b2b9
7
+ data.tar.gz: 4407751fe08bb38ad05c0af7fbaba7b9657d55cddd696a90a62a4b7550f1c57c8ddc5f8c94bd63ed78c6cfb405e51ea96a33dd9b8dba63b42383f77a8032bd51
@@ -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.time # returns tuple (seconds since epoch, microseconds)
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). The operations are not performed atomically.
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
- did_set = @redis.setnx(full_key, value)
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.eval(CAS_SCRIPT, keys: [full_key], argv: [old_value, new_value, ttl_milli])
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
@@ -1,3 +1,3 @@
1
1
  module GCRA
2
- VERSION = '1.0.3'.freeze
2
+ VERSION = '1.0.4'.freeze
3
3
  end
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.3
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: 2018-05-16 00:00:00.000000000 Z
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
- - michael.frister@barzahlen.de
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: {}