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 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: {}