oxblood 0.1.0.dev10 → 0.1.0.dev11
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/.travis.yml +2 -0
- data/Gemfile +0 -2
- data/README.md +14 -15
- data/lib/oxblood/commands/hashes.rb +5 -8
- data/lib/oxblood/commands/transactions.rb +49 -3
- data/lib/oxblood/connection.rb +13 -4
- data/lib/oxblood/pipeline.rb +4 -7
- data/lib/oxblood/pool.rb +3 -22
- data/lib/oxblood/session.rb +21 -1
- data/lib/oxblood/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8748b287262e6e3f061b9c4359472527f8c32937
|
4
|
+
data.tar.gz: a42f3aeea15b7220730a5fdd37bda6f73955b231
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b39975b37b8b7c4ec046b42a4edef9a24e080c63fee98f3ac1455123409c60f4dccd4234200d05a7297847c7dd2d2c85b20266023e7b6502ef45eec69eeca648
|
7
|
+
data.tar.gz: 17fa53c914114183a3460edf8b64e127b5d379aab83ebc8bf97a9cbd35eb5062d9acc18010a6efba44e21e9331a216381357be57dc0f631a9cf473c9c403c6c2
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,9 +4,8 @@
|
|
4
4
|
[](http://rubydoc.info/github/etehtsea/oxblood/master/frames)
|
5
5
|
[](https://travis-ci.org/etehtsea/oxblood)
|
6
6
|
[](https://codeclimate.com/github/etehtsea/oxblood)
|
7
|
-
[](https://codeclimate.com/github/etehtsea/oxblood/coverage)
|
8
7
|
|
9
|
-
|
8
|
+
A straightforward Redis Ruby client.
|
10
9
|
|
11
10
|
## Compatibility
|
12
11
|
|
@@ -17,19 +16,19 @@ An experimental Redis Ruby client.
|
|
17
16
|
|
18
17
|
- Commands:
|
19
18
|
- Cluster (0/20)
|
20
|
-
- Connection
|
19
|
+
- [Connection](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Connection)
|
21
20
|
- Geo (0/6)
|
22
|
-
- Hashes (14/15) (See [#3]
|
21
|
+
- [Hashes](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Hashes) (14/15) (See [#3])
|
23
22
|
- HyperLogLog (0/3)
|
24
|
-
- Keys (18/22) (See [#4], [#6], [#7], [#8])
|
25
|
-
- Lists
|
23
|
+
- [Keys](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Keys) (18/22) (See [#4], [#6], [#7], [#8])
|
24
|
+
- [Lists](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Lists)
|
26
25
|
- Pub/Sub (0/6)
|
27
26
|
- Scripting (0/7)
|
28
|
-
- Server (2/31)
|
29
|
-
- Sets (14/15) (See [#10]
|
30
|
-
- Sorted Sets (15/21) (See [#12], [#13], [#14], [#15])
|
31
|
-
- Strings (23/24) (See [#16]
|
32
|
-
-
|
27
|
+
- [Server](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Server) (2/31)
|
28
|
+
- [Sets](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Sets) (14/15) (See [#10])
|
29
|
+
- [Sorted Sets](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/SortedSets) (15/21) (See [#12], [#13], [#14], [#15])
|
30
|
+
- [Strings](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Strings) (23/24) (See [#16])
|
31
|
+
- [Transactions](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Commands/Transactions)
|
33
32
|
- [Pipeling](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Pipeline)
|
34
33
|
- [Connection pooling](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/Pool)
|
35
34
|
- [Connection resiliency](http://www.rubydoc.info/github/etehtsea/oxblood/master/Oxblood/RSocket)
|
@@ -41,23 +40,23 @@ As a starting point please look at [Oxblood::Pool](http://www.rubydoc.info/githu
|
|
41
40
|
Documentation and usage examples are available on [Rubydoc](http://rubydoc.info/github/etehtsea/oxblood/master/frames).
|
42
41
|
|
43
42
|
## Continuous Integration
|
44
|
-
You can check CI status at [Travis CI](https://travis-ci.org/etehtsea/oxblood
|
43
|
+
You can check CI status at [Travis CI](https://travis-ci.org/etehtsea/oxblood).
|
45
44
|
|
46
45
|
## Contributing
|
47
|
-
|
48
46
|
Bug reports and pull requests are welcome on [GitHub](https://github.com/etehtsea/oxblood).
|
49
47
|
|
50
|
-
|
51
48
|
## License
|
52
|
-
|
53
49
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
54
50
|
|
51
|
+
[#3]: https://github.com/etehtsea/oxblood/issues/3
|
55
52
|
[#4]: https://github.com/etehtsea/oxblood/issues/4
|
56
53
|
[#6]: https://github.com/etehtsea/oxblood/issues/6
|
57
54
|
[#7]: https://github.com/etehtsea/oxblood/issues/7
|
58
55
|
[#8]: https://github.com/etehtsea/oxblood/issues/8
|
56
|
+
[#10]: https://github.com/etehtsea/oxblood/issues/10
|
59
57
|
[#12]: https://github.com/etehtsea/oxblood/issues/12
|
60
58
|
[#13]: https://github.com/etehtsea/oxblood/issues/13
|
61
59
|
[#14]: https://github.com/etehtsea/oxblood/issues/14
|
62
60
|
[#15]: https://github.com/etehtsea/oxblood/issues/15
|
61
|
+
[#16]: https://github.com/etehtsea/oxblood/issues/16
|
63
62
|
[#19]: https://github.com/etehtsea/oxblood/issues/19
|
@@ -1,9 +1,6 @@
|
|
1
1
|
module Oxblood
|
2
2
|
module Commands
|
3
3
|
module Hashes
|
4
|
-
QUEUED = 'QUEUED'.freeze
|
5
|
-
private_constant :QUEUED
|
6
|
-
|
7
4
|
# Removes the specified fields from the hash stored at key
|
8
5
|
# @see http://redis.io/commands/hdel
|
9
6
|
#
|
@@ -21,9 +18,9 @@ module Oxblood
|
|
21
18
|
# @param [String] key under which hash is stored
|
22
19
|
# @param [String] field to check for existence
|
23
20
|
#
|
24
|
-
# @return [
|
21
|
+
# @return [Integer] 1 if the hash contains field and 0 otherwise
|
25
22
|
def hexists(key, field)
|
26
|
-
|
23
|
+
run(:HEXISTS, key, field)
|
27
24
|
end
|
28
25
|
|
29
26
|
# Get the value of a hash field
|
@@ -43,10 +40,10 @@ module Oxblood
|
|
43
40
|
#
|
44
41
|
# @param [String] key under which hash is stored
|
45
42
|
#
|
46
|
-
# @return [
|
43
|
+
# @return [Array] list of fields and their values stored in the hash,
|
44
|
+
# or an empty list when key does not exist.
|
47
45
|
def hgetall(key)
|
48
|
-
|
49
|
-
response == 'QUEUED' ? response : Hash[*response]
|
46
|
+
run(:HGETALL, key)
|
50
47
|
end
|
51
48
|
|
52
49
|
# Increment the integer value of a hash field by the given number
|
@@ -1,13 +1,36 @@
|
|
1
1
|
module Oxblood
|
2
2
|
module Commands
|
3
|
+
# @see https://redis.io/topics/transactions
|
3
4
|
module Transactions
|
4
5
|
# Mark the start of a transaction block
|
5
6
|
# @see http://redis.io/commands/multi
|
6
7
|
#
|
8
|
+
# @example {#exec} will be executed automatically at the end of a block.
|
9
|
+
# session.multi do
|
10
|
+
# session.ping
|
11
|
+
# session.ping
|
12
|
+
# end
|
13
|
+
# # => ['PONG', 'PONG']
|
14
|
+
#
|
15
|
+
# @example Blockless variant.
|
16
|
+
# session.multi
|
17
|
+
# session.incr(:counter0)
|
18
|
+
# session.incr(:counter1)
|
19
|
+
# session.exec
|
20
|
+
#
|
7
21
|
# @return [String] 'OK'
|
8
22
|
# @return [RError] if multi called inside transaction
|
9
23
|
def multi
|
10
|
-
run(:MULTI)
|
24
|
+
response = run(:MULTI).tap do |resp|
|
25
|
+
connection.transaction_mode = true if resp == 'OK'
|
26
|
+
end
|
27
|
+
|
28
|
+
if block_given?
|
29
|
+
yield
|
30
|
+
exec
|
31
|
+
else
|
32
|
+
response
|
33
|
+
end
|
11
34
|
end
|
12
35
|
|
13
36
|
# Execute all commands issued after MULTI
|
@@ -17,7 +40,7 @@ module Oxblood
|
|
17
40
|
# in the atomic transaction
|
18
41
|
# @return [nil] when WATCH was used and execution was aborted
|
19
42
|
def exec
|
20
|
-
run(:EXEC)
|
43
|
+
run(:EXEC).tap { connection.transaction_mode = false }
|
21
44
|
end
|
22
45
|
|
23
46
|
# Discard all commands issued after MULTI
|
@@ -26,7 +49,30 @@ module Oxblood
|
|
26
49
|
# @return [String] 'OK'
|
27
50
|
# @return [RError] if called without transaction started
|
28
51
|
def discard
|
29
|
-
run(:DISCARD)
|
52
|
+
run(:DISCARD).tap { connection.transaction_mode = false }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Watch the given keys to determine execution of the MULTI/EXEC block
|
56
|
+
# @see https://redis.io/commands/watch
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# session.set(:cnt, 0)
|
60
|
+
# session.watch(:cnt)
|
61
|
+
# value = session.get(:cnt).to_i
|
62
|
+
# value += 1
|
63
|
+
# session.multi { session.set(:cnt, value) }
|
64
|
+
# # => `['OK']` or `nil` if `cnt` was modified while was watched
|
65
|
+
# @return [String] 'OK'
|
66
|
+
def watch(*keys)
|
67
|
+
run(:WATCH, keys)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Forget about all watched keys
|
71
|
+
# @see https://redis.io/commands/unwatch
|
72
|
+
#
|
73
|
+
# @return [String] 'OK'
|
74
|
+
def unwatch
|
75
|
+
run(:UNWATCH)
|
30
76
|
end
|
31
77
|
end
|
32
78
|
end
|
data/lib/oxblood/connection.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'oxblood/protocol'
|
2
|
+
require 'oxblood/pipeline'
|
2
3
|
require 'oxblood/rsocket'
|
3
4
|
require 'oxblood/session'
|
4
5
|
|
@@ -9,6 +10,11 @@ module Oxblood
|
|
9
10
|
# @return [RSocket] resilient socket
|
10
11
|
attr_reader :socket
|
11
12
|
|
13
|
+
# @!attribute [rw] transaction_mode
|
14
|
+
# @return [Boolean] transaction status
|
15
|
+
# @api private
|
16
|
+
attr_accessor :transaction_mode
|
17
|
+
|
12
18
|
# Initialize connection to Redis server
|
13
19
|
#
|
14
20
|
# @param [Hash] opts Connection options
|
@@ -23,6 +29,7 @@ module Oxblood
|
|
23
29
|
#
|
24
30
|
# @option opts [String] :path UNIX socket path
|
25
31
|
def initialize(opts = {})
|
32
|
+
@in_transaction = false
|
26
33
|
@socket = RSocket.new(opts)
|
27
34
|
|
28
35
|
session = Session.new(self)
|
@@ -56,10 +63,12 @@ module Oxblood
|
|
56
63
|
Protocol.parse(@socket)
|
57
64
|
end
|
58
65
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
|
62
|
-
|
66
|
+
# Connection transaction status.
|
67
|
+
# @api private
|
68
|
+
#
|
69
|
+
# @return [Boolean, nil] transaction status
|
70
|
+
def in_transaction?
|
71
|
+
transaction_mode
|
63
72
|
end
|
64
73
|
end
|
65
74
|
end
|
data/lib/oxblood/pipeline.rb
CHANGED
@@ -14,7 +14,7 @@ module Oxblood
|
|
14
14
|
# pipeline.echo('!')
|
15
15
|
# pipeline.sync # => ["ping", "PONG", "!"]
|
16
16
|
class Pipeline
|
17
|
-
include
|
17
|
+
include Commands
|
18
18
|
|
19
19
|
attr_reader :connection
|
20
20
|
|
@@ -26,12 +26,9 @@ module Oxblood
|
|
26
26
|
# Sends all commands at once and reads responses
|
27
27
|
# @return [Array] of responses
|
28
28
|
def sync
|
29
|
-
serialized_commands = @commands.map
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@connection.socket.write(serialized_commands.join)
|
34
|
-
@connection.read_responses(@commands.size)
|
29
|
+
serialized_commands = @commands.map { |c| Protocol.build_command(*c) }
|
30
|
+
connection.socket.write(serialized_commands.join)
|
31
|
+
Array.new(@commands.size) { connection.read_response }
|
35
32
|
ensure
|
36
33
|
@commands.clear
|
37
34
|
end
|
data/lib/oxblood/pool.rb
CHANGED
@@ -39,29 +39,10 @@ module Oxblood
|
|
39
39
|
# end # => 'world'
|
40
40
|
def with
|
41
41
|
conn = @pool.checkout
|
42
|
-
|
43
|
-
|
44
|
-
@pool.checkin if conn
|
45
|
-
end
|
46
|
-
|
47
|
-
# Run commands on a connection from pool. Connection is wrapped to
|
48
|
-
# the {Pipeline}. {Pipeline#sync} operation will be executed automatically
|
49
|
-
# at the end of a block.
|
50
|
-
# @yield [pipeline] provide {Pipeline} to a block
|
51
|
-
# @yieldreturn [Array] responses from all executed operations
|
52
|
-
#
|
53
|
-
# @example
|
54
|
-
# pool = Oxblood::Pool.new(size: 8)
|
55
|
-
# pool.pipelined do |pipeline|
|
56
|
-
# pipeline.set('hello', 'world')
|
57
|
-
# pipeline.get('hello')
|
58
|
-
# end # => ['OK', 'world']
|
59
|
-
def pipelined
|
60
|
-
conn = @pool.checkout
|
61
|
-
pipeline = Pipeline.new(conn)
|
62
|
-
yield pipeline
|
63
|
-
pipeline.sync
|
42
|
+
session = Session.new(conn)
|
43
|
+
yield(session)
|
64
44
|
ensure
|
45
|
+
session.discard if conn.in_transaction?
|
65
46
|
@pool.checkin if conn
|
66
47
|
end
|
67
48
|
end
|
data/lib/oxblood/session.rb
CHANGED
@@ -13,7 +13,7 @@ module Oxblood
|
|
13
13
|
# session = Oxblood::Session.new(conn)
|
14
14
|
# session.ping # => 'PONG'
|
15
15
|
class Session
|
16
|
-
include
|
16
|
+
include Commands
|
17
17
|
|
18
18
|
attr_reader :connection
|
19
19
|
|
@@ -21,6 +21,26 @@ module Oxblood
|
|
21
21
|
@connection = connection
|
22
22
|
end
|
23
23
|
|
24
|
+
# Send queries using pipelining.
|
25
|
+
# Sync operation will be executed automatically at the end of a block.
|
26
|
+
#
|
27
|
+
# @see https://redis.io/topics/pipelining
|
28
|
+
#
|
29
|
+
# @yield [pipeline] provide {Pipeline} to a block
|
30
|
+
# @yieldreturn [Array] responses from all executed operations
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# session = Oxblood::Session.new(Oxblood::Connection.new)
|
34
|
+
# session.pipelined do |pipeline|
|
35
|
+
# pipeline.set('hello', 'world')
|
36
|
+
# pipeline.get('hello')
|
37
|
+
# end # => ['OK', 'world']
|
38
|
+
def pipelined
|
39
|
+
pipeline = Pipeline.new(connection)
|
40
|
+
yield pipeline
|
41
|
+
pipeline.sync
|
42
|
+
end
|
43
|
+
|
24
44
|
private
|
25
45
|
|
26
46
|
def run(*command)
|
data/lib/oxblood/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oxblood
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.dev11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Shabanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: connection_pool
|
@@ -155,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
155
|
version: 1.3.1
|
156
156
|
requirements: []
|
157
157
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.6.
|
158
|
+
rubygems_version: 2.6.8
|
159
159
|
signing_key:
|
160
160
|
specification_version: 4
|
161
161
|
summary: A Ruby Redis client
|