redic-rb 1.6

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1e6a500c5ac8d333481dcc65b4c7f9eb9dddc322f80fdc691d73aa0d426fadee
4
+ data.tar.gz: '09da31f87e4089f3100256ad018ec6f0e687c9ed0e46c316b8e404831c3045d4'
5
+ SHA512:
6
+ metadata.gz: a080ef7608225c3587c66f4f6115af50710686218b26e2a95dff8cb67d6baba9a3f8f8566c30872a41a6d014a04afd003650f21f4ef7920c4231e4f78df07e75
7
+ data.tar.gz: 894767f8f0a73c5440ef5dffc237ce4190b92237eb485803d8de9acbb682de65ee04dccd03046abeec6b2bcb3d40e701425d9bcc697f16a0a9ce7bff7bf1404e
data/.gems ADDED
@@ -0,0 +1,2 @@
1
+ cutest -v 1.2.3
2
+ hiredis -v 0.6.3
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /.gs
data/CHANGELOG ADDED
@@ -0,0 +1,35 @@
1
+ 1.5.1
2
+
3
+ - Allow timeout to be changed.
4
+
5
+ 1.5.0
6
+
7
+ - Raise runtime errors when using `call!`.
8
+
9
+ 1.4.1
10
+
11
+ - Reconnect only if URLs differ.
12
+
13
+ 1.4.0
14
+
15
+ - Close connections with Redic#quit.
16
+
17
+ 1.3.0
18
+
19
+ - Improve support for multithreaded environments.
20
+
21
+ 1.2.0
22
+
23
+ - Add Redic#configure.
24
+
25
+ 1.1.1
26
+
27
+ - Redic can now connect to sentinels.
28
+
29
+ 1.1.0
30
+
31
+ - Redic is now compatible with all rubies.
32
+
33
+ 1.0.0
34
+
35
+ - Add a configurable timeout.
data/CONTRIBUTING ADDED
@@ -0,0 +1,19 @@
1
+ This code tries to solve a particular problem with a very simple
2
+ implementation. We try to keep the code to a minimum while making
3
+ it as clear as possible. The design is very likely finished, and
4
+ if some feature is missing it is possible that it was left out on
5
+ purpose. That said, new usage patterns may arise, and when that
6
+ happens we are ready to adapt if necessary.
7
+
8
+ A good first step for contributing is to meet us on IRC and discuss
9
+ ideas. We spend a lot of time on #lesscode at freenode, always ready
10
+ to talk about code and simplicity. If connecting to IRC is not an
11
+ option, you can create an issue explaining the proposed change and
12
+ a use case. We pay a lot of attention to use cases, because our
13
+ goal is to keep the code base simple. Usually the result of a
14
+ conversation is the creation of a different tool.
15
+
16
+ Please don't start the conversation with a pull request. The code
17
+ should come at last, and even though it may help to convey an idea,
18
+ more often than not it draws the attention to a particular
19
+ implementation.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ redic-rb (1.6)
5
+ redis (~> 4.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ awesome_print (1.8.0)
11
+ byebug (11.0.0)
12
+ clap (1.0.0)
13
+ coderay (1.1.2)
14
+ coolline (0.5.0)
15
+ unicode_utils (~> 1.4)
16
+ cutest (1.2.3)
17
+ clap
18
+ hirb (0.7.3)
19
+ hirb-unicode-steakknife (0.0.8)
20
+ hirb (~> 0.5)
21
+ unicode-display_width (~> 1.1)
22
+ method_source (0.9.2)
23
+ pry (0.12.2)
24
+ coderay (~> 1.1.0)
25
+ method_source (~> 0.9.0)
26
+ pry-byebug (3.7.0)
27
+ byebug (~> 11.0)
28
+ pry (~> 0.10)
29
+ pry-coolline (0.2.5)
30
+ coolline (~> 0.5)
31
+ pry-doc (0.13.5)
32
+ pry (~> 0.11)
33
+ yard (~> 0.9.11)
34
+ pry-rails (0.3.9)
35
+ pry (>= 0.10.4)
36
+ redis (4.1.0)
37
+ spirit_hands (2.1.5)
38
+ awesome_print (~> 1.6)
39
+ hirb (~> 0.7)
40
+ hirb-unicode-steakknife (~> 0.0)
41
+ pry (~> 0.10)
42
+ pry-byebug (~> 3.4)
43
+ pry-coolline (~> 0.2)
44
+ pry-doc (~> 0.8)
45
+ pry-rails (~> 0.3)
46
+ unicode-display_width (1.5.0)
47
+ unicode_utils (1.4.0)
48
+ yard (0.9.18)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ cutest (~> 1.2)
55
+ redic-rb!
56
+ spirit_hands (~> 2.1)
57
+
58
+ BUNDLED WITH
59
+ 1.16.1
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013-2014 Michel Martens, Cyril David
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,142 @@
1
+ Redic
2
+ =====
3
+
4
+ Lightweight Redis Client
5
+
6
+ Description
7
+ -----------
8
+
9
+ Lightweight Redis Client inspired by [redigo][redigo], a Redis
10
+ client library for golang.
11
+
12
+ ## Usage
13
+
14
+ ```ruby
15
+ # Accepts a Redis URL and defaults to "redis://127.0.0.1:6379".
16
+ redis = Redic.new
17
+
18
+ # Processes the command and returns the response.
19
+ redis.call("SET", "foo", "bar")
20
+
21
+ assert_equal "bar", redis.call("GET", "foo")
22
+
23
+ # Pipelining is implemented by buffering commands,
24
+ # then calling Redic#commit
25
+ redis.queue("SET", "foo", "bar")
26
+ redis.queue("GET", "foo")
27
+
28
+ assert_equal ["OK", "bar"], redis.commit
29
+ ```
30
+
31
+ You can provide the password and the database to be selected. The
32
+ format for Redis URLs is `redis://user:pass@host:port/db`. As
33
+ Redis only needs a password for authentication, the user can be
34
+ omitted:
35
+
36
+ ```ruby
37
+ # Connect to localhost:6380 using "bar" as password and use the
38
+ # database 2. Both AUTH and SELECT commands are issued after
39
+ # connecting. The user part of the URL is not provided.
40
+ redis = Redic.new("redis://:bar@localhost:6380/2")
41
+ ```
42
+
43
+ It is also possible to configure a timeout for the connection. The
44
+ default timeout is 10 seconds.
45
+
46
+ ```ruby
47
+ # Timeout expressed in microseconds.
48
+ redis = Redic.new(REDIS_URL, 2_000_000)
49
+ redis.timeout == 2_000_000 #=> true
50
+ ```
51
+ A client can be re-configured, forcing the next connection to
52
+ be established with the new details:
53
+
54
+ ```ruby
55
+ redis = Redic.new("redis://localhost:6379")
56
+ redis.configure("redis://localhost:6380")
57
+ ```
58
+
59
+ Here's one final example using both a Redis URL and a timeout:
60
+
61
+ ```ruby
62
+ # It's recommended to store the REDIS_URL as an environment
63
+ # variable. Use `fetch` to retrieve values that must be present,
64
+ # as it raises an error if the value is not found.
65
+ REDIS_URL = ENV.fetch("REDIS_URL")
66
+ REDIS_TIMEOUT = ENV.fetch("REDIS_TIMEOUT")
67
+
68
+ redis = Redic.new(REDIS_URL, REDIS_TIMEOUT)
69
+ ```
70
+
71
+ Both the initializer and the `configure` method accept a `URL` and
72
+ a `timeout`.
73
+
74
+ In order to close the connection, call `quit`:
75
+
76
+ ```ruby
77
+ redis = Redic.new("redis://localhost:6379")
78
+ redis.quit
79
+ ```
80
+
81
+ With that command, `"QUIT"` is sent to Redis and the socket is closed.
82
+
83
+ ## Differences with redis-rb
84
+
85
+ Redic uses [hiredis][hiredis] for the connection and for parsing
86
+ the replies. There are no alternative connection drivers. Unlike
87
+ [redis-rb][redis-rb] it doesn't define all the Redis commands, and
88
+ instead it acts as a transport layer. The lock provided is smaller
89
+ than that of redis-rb, as it only wraps the writing and reading from
90
+ the connection. So even if both clients are thread-safe by default,
91
+ the peformance of a smaller lock is marginally better.
92
+
93
+ [redigo]: https://github.com/garyburd/redigo
94
+ [hiredis]: https://github.com/pietern/hiredis-rb
95
+ [redis-rb]: https://github.com/redis/redis-rb
96
+
97
+ ## Limitations
98
+
99
+ When a client enters a subscribed mode, further reads to retrieve the
100
+ messages are not thread safe. It is very important to take this into
101
+ account and to create a different client if you need to send different
102
+ operations while a client is subscribed to a channel.
103
+
104
+ ```ruby
105
+ # Example of pub/sub usage.
106
+ c1 = Redic.new
107
+ c2 = Redic.new
108
+
109
+ # After this command, the client is no longer thread safe.
110
+ c1.call("SUBSCRIBE", "foo")
111
+
112
+ # That's why we need to publish from a different connection.
113
+ c2.call("PUBLISH", "foo")
114
+
115
+ # Note that this operation is not thread safe.
116
+ assert_equal ["message", "foo", "value1"], c1.client.read
117
+ ```
118
+
119
+ You can wrap thread unsafe operations in a mutex:
120
+
121
+ ```ruby
122
+ redis = Redic.new
123
+
124
+ mutex = Mutex.new
125
+
126
+ mutex.synchronize do
127
+ redis.call("MONITOR")
128
+
129
+ # Display every command sent to Redis.
130
+ loop do
131
+ puts redis.client.read
132
+ end
133
+ end
134
+ ```
135
+
136
+ ## Installation
137
+
138
+ You can install it using rubygems.
139
+
140
+ ```
141
+ $ gem install redic
142
+ ```
data/bin/console ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "redic"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,116 @@
1
+ require_relative "connection"
2
+ require "uri"
3
+ require "redis"
4
+
5
+ class Redic
6
+ class Client
7
+ EMPTY = "".freeze
8
+ SLASH = "/".freeze
9
+
10
+ attr_accessor :timeout
11
+
12
+ def initialize(url, timeout)
13
+ @semaphore = Mutex.new
14
+ @connection = false
15
+
16
+ configure(url, timeout)
17
+ end
18
+
19
+ def configure(url, timeout)
20
+ disconnect!
21
+
22
+ @uri = URI.parse(url)
23
+ @timeout = timeout
24
+ end
25
+
26
+ def read
27
+ #@connection.read
28
+ @response
29
+ end
30
+
31
+ def write(command)
32
+ #@connection.write(command)
33
+ cmd_name = command.shift.to_s.downcase
34
+ block = command.find{ |cmd| cmd.is_a? Proc }
35
+ #binding.pry if cmd_name == "subscribe"
36
+ @response = if command.empty?
37
+ @connection.send(cmd_name)
38
+ else
39
+ @connection.send(cmd_name, *command, &block)
40
+ end
41
+ rescue => e
42
+ return raise e if e.message =~ /ERR invalid DB index/
43
+ return raise e if e.message =~ /ERR invalid password/
44
+ @response = RuntimeError.new(e.message)
45
+ end
46
+
47
+ def connect
48
+ establish_connection unless connected?
49
+
50
+ @semaphore.synchronize do
51
+ yield
52
+ end
53
+ rescue Errno::ECONNRESET
54
+ @connection = false
55
+ retry
56
+ end
57
+
58
+ def connected?
59
+ @connection && @connection.connected?
60
+ end
61
+
62
+ def disconnect!
63
+ if connected?
64
+ @connection.disconnect!
65
+ @connection = false
66
+ end
67
+ end
68
+
69
+ def quit
70
+ if connected?
71
+ assert_ok(call("QUIT"))
72
+ disconnect!
73
+
74
+ true
75
+ else
76
+ false
77
+ end
78
+ end
79
+
80
+ private
81
+ def establish_connection
82
+ begin
83
+ #Redic::Connection.new(@uri, @timeout)
84
+ @connection = Redis.new(url: @uri)
85
+ raise StandardError if @connection.ping != "PONG"
86
+ rescue StandardError => err
87
+ raise err, "Can't connect to: #{@uri} because: #{err.message}"
88
+ end
89
+
90
+ if @uri.scheme != "unix"
91
+ if @uri.password
92
+ assert_ok(call("AUTH", @uri.password))
93
+ end
94
+
95
+ if @uri.path != EMPTY && @uri.path != SLASH
96
+ assert_ok(call("SELECT", @uri.path[1..-1]))
97
+ end
98
+ end
99
+ end
100
+
101
+ def call(*args)
102
+ @semaphore.synchronize do
103
+ write(args)
104
+ read
105
+ end
106
+ end
107
+
108
+ def assert(value, error)
109
+ raise error unless value
110
+ end
111
+
112
+ def assert_ok(reply)
113
+ assert(reply == "OK", reply)
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,17 @@
1
+ #require "hiredis/connection"
2
+ #
3
+ #class Redic
4
+ # module Connection
5
+ # def self.new(uri, timeout)
6
+ # connection = Hiredis::Connection.new
7
+ #
8
+ # if uri.scheme == "unix"
9
+ # connection.connect_unix(uri.path, timeout)
10
+ # else
11
+ # connection.connect(uri.host, uri.port, timeout)
12
+ # end
13
+ #
14
+ # connection
15
+ # end
16
+ # end
17
+ #end
data/lib/redic.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'redis'
2
+ require_relative "redic/client"
3
+
4
+ class Redic
5
+ attr :url
6
+ attr :client
7
+
8
+ def initialize(url = "redis://127.0.0.1:6379", timeout = 10_000_000)
9
+ @url = url
10
+ @client = Redic::Client.new(url, timeout)
11
+ @buffer = Hash.new { |h, k| h[k] = [] }
12
+ end
13
+
14
+ def buffer
15
+ @buffer[Thread.current.object_id]
16
+ end
17
+
18
+ def reset
19
+ @buffer.delete(Thread.current.object_id)
20
+ end
21
+
22
+ def clear
23
+ @buffer.clear
24
+ end
25
+
26
+ def configure(url, timeout = 10_000_000)
27
+ if @url != url
28
+ @url = url
29
+ @client.configure(url, timeout)
30
+ end
31
+ end
32
+
33
+ def call(*args)
34
+ @client.connect do
35
+ @client.write(args)
36
+ @client.read
37
+ end
38
+ end
39
+
40
+ def call!(*args)
41
+ reply = call(*args)
42
+
43
+ if RuntimeError === reply
44
+ raise reply
45
+ end
46
+
47
+ return reply
48
+ end
49
+
50
+ def queue(*args)
51
+ buffer << args
52
+ end
53
+
54
+ def commit
55
+ @client.connect do
56
+ buffer.map do |args|
57
+ @client.write(args)
58
+ end
59
+ end
60
+ ensure
61
+ reset
62
+ end
63
+
64
+ def timeout
65
+ @client.timeout
66
+ end
67
+
68
+ def timeout=(timeout)
69
+ @client.timeout = timeout
70
+ end
71
+
72
+ def quit
73
+ @client.quit
74
+ end
75
+ end
data/makefile ADDED
@@ -0,0 +1,2 @@
1
+ test:
2
+ RUBYLIB=./lib cutest tests/*.rb
data/redic-rb.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "redic-rb"
5
+ s.version = "1.6"
6
+ s.summary = "Lightweight Redis Client"
7
+ s.description = "Lightweight Redis Client"
8
+ s.authors = ["Michel Martens", "Cyril David", "Diego Gomez"]
9
+ s.email = ["michel@soveran.com", "cyx@cyx.is", "diego.f.gomez.pardo@gmail.com"]
10
+ s.homepage = "https://github.com/degz/redic-rb"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.license = "MIT"
13
+
14
+ s.add_dependency "redis", "~> 4.1"
15
+
16
+ s.add_development_dependency "spirit_hands", "~> 2.1"
17
+ s.add_development_dependency "cutest", "~> 1.2"
18
+
19
+ end
@@ -0,0 +1,54 @@
1
+ require "cutest"
2
+ require_relative "../lib/redic"
3
+
4
+ REDIS_URL = "redis://localhost:6379/"
5
+
6
+ prepare do
7
+ c = Redic.new(REDIS_URL)
8
+
9
+ begin
10
+ c.call("FLUSHDB")
11
+ rescue
12
+ c.call("AUTH", "foo")
13
+ c.call("FLUSHDB")
14
+ c.call("CONFIG", "SET", "requirepass", "")
15
+ end
16
+ end
17
+
18
+ test "multiple threads" do
19
+
20
+ cs = Array.new
21
+
22
+ c = Redic.new(REDIS_URL)
23
+
24
+ c.queue("SET", "foo", "1")
25
+
26
+ t1 = Thread.new do
27
+ c.queue("SET", "bar", "2")
28
+ end
29
+
30
+ t2 = Thread.new do
31
+ c.queue("SET", "baz", "3")
32
+ c.commit
33
+ end
34
+
35
+ t1.join
36
+ t2.join
37
+
38
+ assert_equal nil, c.call("GET", "foo")
39
+ assert_equal nil, c.call("GET", "bar")
40
+ assert_equal "3", c.call("GET", "baz")
41
+
42
+ c.commit
43
+
44
+ # The buffer for `c` still exists
45
+ assert_equal "1", c.call("GET", "foo")
46
+
47
+ # Buffer for the thread that didn't commit is the only one left
48
+ assert_equal 1, c.instance_variable_get("@buffer").keys.size
49
+
50
+ c.clear
51
+
52
+ # All buffers are cleared
53
+ assert_equal 0, c.instance_variable_get("@buffer").keys.size
54
+ end
@@ -0,0 +1,232 @@
1
+ require "cutest"
2
+ require_relative "../lib/redic"
3
+ require 'pry'
4
+
5
+ REDIS_URL = "redis://localhost:6379/0"
6
+
7
+ prepare do
8
+ c = Redic.new(REDIS_URL)
9
+
10
+ begin
11
+ c.call!("FLUSHDB").inspect
12
+ rescue
13
+ c.call!("AUTH", "foo")
14
+ c.call!("SELECT", "0")
15
+ c.call!("FLUSHDB")
16
+ c.call!("CONFIG", "SET", "requirepass", "")
17
+ end
18
+ end
19
+
20
+ setup do
21
+ Redic.new(REDIS_URL)
22
+ end
23
+
24
+ test "url" do |c|
25
+ assert_equal "redis://localhost:6379/0", c.url
26
+ end
27
+
28
+ test "select db from url" do |c1|
29
+
30
+ # Connect to db 1
31
+ c2 = Redic.new("redis://localhost:6379/2")
32
+
33
+ c2.call("FLUSHDB")
34
+
35
+ # Set a value in db 0
36
+ c1.call("SET", "foo", "bar")
37
+
38
+ assert_equal(1, c1.call("DBSIZE"))
39
+ assert_equal(0, c2.call("DBSIZE"))
40
+ end
41
+
42
+ test "error when selecting db from url" do
43
+ c2 = Redic.new("redis://localhost:6379/foo")
44
+
45
+ assert_raise(RuntimeError) do
46
+
47
+ # Connection is lazy, send a command
48
+ c2.call("PING")
49
+ end
50
+ end
51
+
52
+ test "error when authenticating from url" do |c1|
53
+
54
+ # Configure password as "foo"
55
+ c1.call("CONFIG", "SET", "requirepass", "foo")
56
+
57
+ # The password provided is wrong
58
+ c2 = Redic.new("redis://:bar@localhost:6379/")
59
+
60
+ assert_raise(RuntimeError) do
61
+
62
+ # Connection is lazy, send a command
63
+ c2.call("PING")
64
+ end
65
+
66
+ c3 = Redic.new("redis://:foo@localhost:6379/")
67
+ assert_equal "PONG", c3.call("PING")
68
+
69
+ # Remove password
70
+ c3.call("CONFIG", "SET", "requirepass", "")
71
+ end
72
+
73
+ #test "Can connect to sentinel" do
74
+ # c2 = Redic.new "redis://localhost:26379"
75
+ # c2.call "SENTINEL", "masters"
76
+ #end
77
+
78
+ test "timeout" do |c1|
79
+
80
+ # Default timeout is 10 seconds
81
+ assert_equal 10_000_000, c1.timeout
82
+
83
+ # Timeout configured to 200_000 microseconds
84
+ c2 = Redic.new(REDIS_URL, 200_000)
85
+
86
+ assert_equal 200_000, c2.timeout
87
+
88
+ # Change timeout to 5 seconds
89
+ c2.timeout = 5_000_000
90
+
91
+ assert_equal 5_000_000, c2.timeout
92
+ end
93
+
94
+ test "normal commands" do |c|
95
+ c.call("SET", "foo", "bar")
96
+
97
+ assert_equal "bar", c.call("GET", "foo")
98
+ end
99
+
100
+ test "pipelining" do |c|
101
+ c.queue("SET", "foo", "perro")
102
+ c.queue("GET", "foo")
103
+
104
+ assert_equal ["OK", "perro"], c.commit
105
+ end
106
+
107
+ test "multi/exec" do |c|
108
+ c.queue("MULTI")
109
+ c.queue("SET", "foo", "bar")
110
+ c.queue("EXEC")
111
+
112
+ assert_equal ["OK", "QUEUED", ["OK"]], c.commit
113
+ end
114
+
115
+ test "runtime errors" do |c|
116
+ res = c.call("KABLAMMO")
117
+
118
+ assert res.is_a?(RuntimeError)
119
+ end
120
+
121
+ test "encoding" do |c|
122
+ Encoding.default_external = "UTF-8"
123
+
124
+ c.call("SET", "foo", "שלום")
125
+
126
+ assert_equal "Shalom שלום", "Shalom " + c.call("GET", "foo")
127
+
128
+ end if defined?(Encoding)
129
+
130
+ test "errors in pipeline" do |c|
131
+ c.queue("SET", "foo", "bar")
132
+ c.queue("INCR", "foo")
133
+ c.queue("GET", "foo")
134
+
135
+ res = c.commit
136
+
137
+ assert "OK" == res[0]
138
+ assert RuntimeError === res[1]
139
+ assert "bar" == res[2]
140
+ end
141
+
142
+ test "thread safety" do |c|
143
+ c.call("SET", "foo", 1)
144
+ c.call("SET", "bar", 2)
145
+
146
+ foos, bars = nil, nil
147
+
148
+ t1 = Thread.new do
149
+ foos = Array.new(100) { c.call("GET", "foo") }
150
+ end
151
+
152
+ t2 = Thread.new do
153
+ bars = Array.new(100) { c.call("GET", "bar") }
154
+ end
155
+
156
+ t1.join
157
+ t2.join
158
+
159
+ assert_equal ["1"], foos.uniq
160
+ assert_equal ["2"], bars.uniq
161
+ end
162
+
163
+ test "blocking commands" do |c1|
164
+ c2 = Redic.new
165
+ r = nil
166
+
167
+ t1 = Thread.new do
168
+ r = c1.call("BLPOP", "foo", 5)
169
+ end
170
+
171
+ t2 = Thread.new do
172
+ c2.call("RPUSH", "foo", "value")
173
+ end
174
+
175
+ t1.join
176
+ t2.join
177
+
178
+ assert_equal ["foo", "value"], r
179
+ end
180
+
181
+ #test "pub/sub" do |c1|
182
+ # c2 = Redic.new
183
+ #
184
+ # binding.pry
185
+ # res = c1.call("SUBSCRIBE", "foo", Proc.new{})
186
+ # assert_equal ["subscribe", "foo", 1], res
187
+ #
188
+ # c2.call("PUBLISH", "foo", "value1")
189
+ # c2.call("PUBLISH", "foo", "value2")
190
+ #
191
+ # assert_equal ["message", "foo", "value1"], c1.client.read
192
+ # assert_equal ["message", "foo", "value2"], c1.client.read
193
+ #
194
+ # c1.call("UNSUBSCRIBE", "foo")
195
+ #
196
+ # assert_equal "PONG", c1.call("PING")
197
+ #end
198
+
199
+ test "reconnect" do |c1|
200
+ url = "redis://:foo@localhost:6379/"
201
+
202
+ assert url != c1.url
203
+
204
+ c1.call("CONFIG", "SET", "requirepass", "foo")
205
+
206
+ c1.configure(url)
207
+
208
+ assert url == c1.url
209
+ assert url.object_id == c1.url.object_id
210
+
211
+ # Reconfigure only if URLs differ
212
+ c1.configure(url.dup)
213
+
214
+ # No reconnection ocurred
215
+ assert url.object_id == c1.url.object_id
216
+
217
+ assert_equal "PONG", c1.call("PING")
218
+ end
219
+
220
+ test "disconnect" do |c1|
221
+
222
+ # Connection is lazy
223
+ assert_equal false, c1.client.connected?
224
+ assert_equal false, c1.quit
225
+
226
+ c1.call("PING")
227
+
228
+ assert_equal true, c1.client.connected?
229
+ assert_equal true, c1.quit
230
+
231
+ assert_equal false, c1.client.connected?
232
+ end
@@ -0,0 +1,27 @@
1
+ require "cutest"
2
+ require_relative "../lib/redic"
3
+
4
+ setup do
5
+ Redic.new("unix:///tmp/redis.6379.sock")
6
+ end
7
+
8
+ test "normal commands" do |c|
9
+ c.call("SET", "foo", "bar")
10
+
11
+ assert_equal "bar", c.call("GET", "foo")
12
+ end
13
+
14
+ test "pipelining" do |c|
15
+ c.queue("SET", "foo", "bar")
16
+ c.queue("GET", "foo")
17
+
18
+ assert_equal ["OK", "bar"], c.commit
19
+ end
20
+
21
+ test "multi/exec" do |c|
22
+ c.queue("MULTI")
23
+ c.queue("SET", "foo", "bar")
24
+ c.queue("EXEC")
25
+
26
+ assert_equal ["OK", "QUEUED", ["OK"]], c.commit
27
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redic-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.6'
5
+ platform: ruby
6
+ authors:
7
+ - Michel Martens
8
+ - Cyril David
9
+ - Diego Gomez
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2019-03-11 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: redis
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '4.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '4.1'
29
+ - !ruby/object:Gem::Dependency
30
+ name: spirit_hands
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '2.1'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '2.1'
43
+ - !ruby/object:Gem::Dependency
44
+ name: cutest
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.2'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '1.2'
57
+ description: Lightweight Redis Client
58
+ email:
59
+ - michel@soveran.com
60
+ - cyx@cyx.is
61
+ - diego.f.gomez.pardo@gmail.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".gems"
67
+ - ".gitignore"
68
+ - CHANGELOG
69
+ - CONTRIBUTING
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE
73
+ - README.md
74
+ - bin/console
75
+ - bin/setup
76
+ - lib/redic.rb
77
+ - lib/redic/client.rb
78
+ - lib/redic/connection.rb
79
+ - makefile
80
+ - redic-rb.gemspec
81
+ - tests/multithreaded_test.rb
82
+ - tests/redic_test.rb
83
+ - tests/unix_test.rb
84
+ homepage: https://github.com/degz/redic-rb
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.7.3
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Lightweight Redis Client
108
+ test_files: []