redis-prescription 2.0.0 → 2.2.0

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
  SHA256:
3
- metadata.gz: 3e78c33e47df77d8456a6207e85758665624c1513637d4cd67a88fc10430045a
4
- data.tar.gz: 9729555b027ec9d4d7acc41a2c6bd6b43e36f3d2d21a6721d503020c799ae41e
3
+ metadata.gz: c503c680688ac288e5d3b9e59314c20055c10239b31733de6855f6a78ed90d3e
4
+ data.tar.gz: f0a2373d51deb922ac02bb8283e05cb583dc3578f95ea8f4923bba2d1a3058e1
5
5
  SHA512:
6
- metadata.gz: 263da116f96133dedd46869901cb455bb8dde63c8278fcef253aa9b62e64c524b28caba8ccb496662e16ea6ce4b710c54cce044b6fdd14974ddc38969a393536
7
- data.tar.gz: ab11c229344bb840896bb87ead1192d3fbc9d8db97de94806699ced01dd20f0a3f0449594a485590becb0cc95d02aeafd2ec427b6e3e38858b818f42f352fe23
6
+ metadata.gz: 516e413b8da8d7dace049f9169c307d3a87b1ee52ecdc759368f3012d2d51e6b44732d38a2980635bc5acb1015436960c48fe17239edd734101feda83d18c503
7
+ data.tar.gz: 2c07386fbc7fb53a0a8093df08a35ed6d366a37084df8823cc49685cf95034e5599f7aeacb2fd502ebef6d4f0654f244988e86bd7bd26bfd30c3f0f7741d079b
data/README.adoc CHANGED
@@ -45,6 +45,8 @@ This library aims to support and is tested against:
45
45
  ** 4.7.x
46
46
  ** 4.8.x
47
47
  ** 5.0.x
48
+ * https://github.com/resque/redis-namespace[redis-namespace]
49
+ ** 1.10.x
48
50
  * https://github.com/redis-rb/redis-client[redis-client]
49
51
  ** 0.12.x
50
52
  ** 0.13.x
@@ -63,7 +65,8 @@ patches in a timely fashion. If critical issues for a particular implementation
63
65
  exist at the time of a major release, support for that Ruby version may be
64
66
  dropped.
65
67
 
66
- Same rules apply to *Redis Server*, *redis-rb*, and *redis-client* support.
68
+ The same applies to *Redis Server*, *redis-rb*, *redis-namespace*,
69
+ and *redis-client* support.
67
70
 
68
71
 
69
72
  == Similar Projects
@@ -14,6 +14,10 @@ class RedisPrescription
14
14
  @redis = redis
15
15
  end
16
16
 
17
+ def adapter_name
18
+ "redis"
19
+ end
20
+
17
21
  def eval(script, keys, argv)
18
22
  @redis.eval(script, keys, argv)
19
23
  rescue ::Redis::CommandError => e
@@ -17,6 +17,10 @@ class RedisPrescription
17
17
  @redis = redis
18
18
  end
19
19
 
20
+ def adapter_name
21
+ "redis-client"
22
+ end
23
+
20
24
  def eval(script, keys, argv)
21
25
  @redis.call("EVAL", script, keys.size, *keys, *argv)
22
26
  rescue ::RedisClient::CommandError => e
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../errors"
4
+
5
+ class RedisPrescription
6
+ module Adapters
7
+ # redis-namespace adapter
8
+ class RedisNamespace
9
+ def self.adapts?(redis)
10
+ defined?(::Redis::Namespace) && redis.is_a?(::Redis::Namespace)
11
+ end
12
+
13
+ def initialize(redis)
14
+ @redis = redis
15
+ end
16
+
17
+ def adapter_name
18
+ "redis-namespace"
19
+ end
20
+
21
+ def eval(script, keys, argv)
22
+ @redis.eval(script, keys, argv)
23
+ rescue ::Redis::CommandError => e
24
+ raise CommandError, e.message
25
+ end
26
+
27
+ def evalsha(digest, keys, argv)
28
+ @redis.evalsha(digest, keys, argv)
29
+ rescue ::Redis::CommandError => e
30
+ raise CommandError, e.message
31
+ end
32
+
33
+ def purge!
34
+ @redis.redis.script("flush")
35
+ @redis.redis.flushdb
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "./adapters/redis"
4
4
  require_relative "./adapters/redis_client"
5
+ require_relative "./adapters/redis_namespace"
5
6
 
6
7
  class RedisPrescription
7
8
  # @api internal
@@ -10,6 +11,7 @@ class RedisPrescription
10
11
  def [](redis)
11
12
  return Adapters::Redis.new(redis) if Adapters::Redis.adapts?(redis)
12
13
  return Adapters::RedisClient.new(redis) if Adapters::RedisClient.adapts?(redis)
14
+ return Adapters::RedisNamespace.new(redis) if Adapters::RedisNamespace.adapts?(redis)
13
15
 
14
16
  raise TypeError, "Unsupported redis client: #{redis.class}"
15
17
  end
@@ -10,17 +10,82 @@ class RedisPrescription
10
10
 
11
11
  # Lua script eval/evalsha failure
12
12
  class ScriptError < Error
13
- # Lua script source.
13
+ # rubocop:disable Layout/LineLength
14
+ LUA_ERROR_MESSAGE = %r{
15
+ # * Error compiling script:
16
+ # ** Redis 6.0, 6.2, 7.0
17
+ # *** ERR Error compiling script (new function): user_script:7: unexpected symbol near '!'
18
+ # * Error running script:
19
+ # ** Redis 6.0, 6.2
20
+ # *** ERR Error running script (call to f_64203334c42d5690c2d008a78aa7789f5b83e5bb): @user_script:4: user_script:4: attempt to perform arithmetic on a string value
21
+ # ** Redis 7.0
22
+ # *** ERR user_script:4: attempt to perform arithmetic on a string value script: 64203334c42d5690c2d008a78aa7789f5b83e5bb, on @user_script:4.
23
+ \A
24
+ ERR\s
25
+ (?:
26
+ Error\scompiling\sscript\s\([^)]+\):\s # Redis 6.0, 6.2, 7.0
27
+ .+:(?<loc>\d+):\s # Redis 6.0, 6.2, 7.0
28
+ (?<message>.+) # Redis 6.0, 6.2, 7.0
29
+ |
30
+ (?:Error\srunning\sscript\s\([^)]+\):\s@\S+\s)? # Redis 6.0, 6.2
31
+ .+:(?<loc>\d+):\s # Redis 6.0, 6.2, 7.0
32
+ (?<message>.+?) # Redis 6.0, 6.2, 7.0
33
+ (?::\s\h+,\son\s@[^:]+:\d+\.)? # Redis 7.0
34
+ )
35
+ \z
36
+ }x
37
+ private_constant :LUA_ERROR_MESSAGE
38
+ # rubocop:enable Layout/LineLength
39
+
40
+ # Lua script source
14
41
  #
15
42
  # @return [String]
16
43
  attr_reader :source
17
44
 
45
+ # Line of code where error was encountered
46
+ #
47
+ # @return [Integer?]
48
+ attr_reader :loc
49
+
18
50
  # @param message [String]
19
- # @param source [String]
51
+ # @param source [#to_s]
20
52
  def initialize(message, source)
21
- @source = source
53
+ @source = -source.to_s
54
+
55
+ if (parsed = LUA_ERROR_MESSAGE.match(message))
56
+ @loc = parsed[:loc].to_i
57
+ message = [parsed[:message], excerpt(@source, @loc)].compact.join("\n\n")
58
+ end
22
59
 
23
60
  super(message)
24
61
  end
62
+
63
+ private
64
+
65
+ def excerpt(source, loc)
66
+ lines = excerpt_lines(source, loc)
67
+ gutter = lines.map(&:first).max.to_s.length
68
+
69
+ lines.map! do |(pos, line)|
70
+ format(pos == loc ? "\t%#{gutter}d > %s" : "\t%#{gutter}d | %s", pos, line).rstrip
71
+ end
72
+
73
+ lines.join("\n")
74
+ rescue => e
75
+ warn "Failed extracting source excerpt: #{e.message}"
76
+ nil
77
+ end
78
+
79
+ def excerpt_lines(source, loc)
80
+ lines = source.lines
81
+ pos = loc - 1 # reported line of code is 1-offset
82
+ min = pos - 2 # 2 lines of head context
83
+ max = pos + 2 # 2 lines of tail context
84
+
85
+ min = 0 if min.negative?
86
+ max = lines.size - 1 if lines.size <= max
87
+
88
+ (min..max).map { |i| [i.succ, lines[i]] }
89
+ end
25
90
  end
26
91
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  class RedisPrescription
4
4
  # Gem version.
5
- VERSION = "2.0.0"
5
+ VERSION = "2.2.0"
6
6
  end
@@ -30,7 +30,7 @@ class RedisPrescription
30
30
  # @return [String]
31
31
  attr_reader :digest
32
32
 
33
- # @param source [#to_s] Lua script.
33
+ # @param source [#to_s] Lua script
34
34
  def initialize(source)
35
35
  @source = -source.to_s
36
36
  @digest = Digest::SHA1.hexdigest(@source).freeze
@@ -44,21 +44,13 @@ class RedisPrescription
44
44
  # @raise [ScriptError] if script execution failed
45
45
  # @return depends on the script
46
46
  def call(redis, keys: EMPTY_LIST, argv: EMPTY_LIST)
47
- unpool(redis) { |r| evalsha_with_fallback(r, keys, argv) }
47
+ evalsha_with_fallback(Adapters[redis], keys, argv)
48
48
  rescue CommandError => e
49
- raise ScriptError.new(e.message, @script)
49
+ raise ScriptError.new(e.message, @source)
50
50
  end
51
51
 
52
52
  private
53
53
 
54
- def unpool(redis)
55
- if redis.respond_to?(:with)
56
- redis.with { |r| yield Adapters[r] }
57
- else
58
- yield Adapters[redis]
59
- end
60
- end
61
-
62
54
  def evalsha_with_fallback(redis, keys, argv)
63
55
  redis.evalsha(@digest, keys, argv)
64
56
  rescue CommandError => e
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-prescription
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Zapparov
@@ -26,6 +26,7 @@ files:
26
26
  - lib/redis_prescription/adapters.rb
27
27
  - lib/redis_prescription/adapters/redis.rb
28
28
  - lib/redis_prescription/adapters/redis_client.rb
29
+ - lib/redis_prescription/adapters/redis_namespace.rb
29
30
  - lib/redis_prescription/errors.rb
30
31
  - lib/redis_prescription/version.rb
31
32
  homepage: https://gitlab.com/ixti/redis-prescription
@@ -35,7 +36,7 @@ metadata:
35
36
  homepage_uri: https://gitlab.com/ixti/redis-prescription
36
37
  source_code_uri: https://gitlab.com/ixti/redis-prescription
37
38
  bug_tracker_uri: https://gitlab.com/ixti/redis-prescription/issues
38
- changelog_uri: https://gitlab.com/ixti/redis-prescription/blob/v2.0.0/CHANGES.md
39
+ changelog_uri: https://gitlab.com/ixti/redis-prescription/blob/v2.2.0/CHANGES.md
39
40
  rubygems_mfa_required: 'true'
40
41
  post_install_message:
41
42
  rdoc_options: []