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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa40f0d5b2f3279151d1689abb30900a658e4b42
4
- data.tar.gz: 1dab3c062674dc0cacae8ed38bd54b01965fc962
3
+ metadata.gz: 8748b287262e6e3f061b9c4359472527f8c32937
4
+ data.tar.gz: a42f3aeea15b7220730a5fdd37bda6f73955b231
5
5
  SHA512:
6
- metadata.gz: cca554b76261801ee8805aef706002efcfbed3412cf93105f74885b329e80b3d2632b1e53b586199bf610c0f584f856d744fd8eede3b6ccc58ac83b25c355b8d
7
- data.tar.gz: 26168ad1e57c524f137374865648680f4d684f0ea4ade6a71664cf9d7ee70507cfcfc5c9ab946e42bb91fd189ce7fd89218fbb2141453404d211a98a0785924b
6
+ metadata.gz: b39975b37b8b7c4ec046b42a4edef9a24e080c63fee98f3ac1455123409c60f4dccd4234200d05a7297847c7dd2d2c85b20266023e7b6502ef45eec69eeca648
7
+ data.tar.gz: 17fa53c914114183a3460edf8b64e127b5d379aab83ebc8bf97a9cbd35eb5062d9acc18010a6efba44e21e9331a216381357be57dc0f631a9cf473c9c403c6c2
data/.travis.yml CHANGED
@@ -5,8 +5,10 @@ language: ruby
5
5
  rvm:
6
6
  - 2.2.5
7
7
  - 2.3.1
8
+ - 2.4.0
8
9
  - jruby-9.0.5.0
9
10
  - jruby-9.1.5.0
11
+ - jruby-9.1.7.0
10
12
 
11
13
  services:
12
14
  - redis-server
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- gem 'codeclimate-test-reporter', group: :test, require: nil
data/README.md CHANGED
@@ -4,9 +4,8 @@
4
4
  [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/etehtsea/oxblood/master/frames)
5
5
  [![Build Status](https://travis-ci.org/etehtsea/oxblood.svg?branch=master)](https://travis-ci.org/etehtsea/oxblood)
6
6
  [![Code Climate](https://codeclimate.com/github/etehtsea/oxblood/badges/gpa.svg)](https://codeclimate.com/github/etehtsea/oxblood)
7
- [![Test Coverage](https://codeclimate.com/github/etehtsea/oxblood/badges/coverage.svg)](https://codeclimate.com/github/etehtsea/oxblood/coverage)
8
7
 
9
- An experimental Redis Ruby client.
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](https://github.com/etehtsea/oxblood/issues/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](https://github.com/etehtsea/oxblood/issues/10))
30
- - Sorted Sets (15/21) (See [#12], [#13], [#14], [#15])
31
- - Strings (23/24) (See [#16](https://github.com/etehtsea/oxblood/issues/16))
32
- - Transaction (3/5) (See [#19])
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.svg?branch=master).
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 [Boolean] do hash contains field or not
21
+ # @return [Integer] 1 if the hash contains field and 0 otherwise
25
22
  def hexists(key, field)
26
- 1 == run(:HEXISTS, key, field)
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 [Hash] of fields and their values
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
- response = run(:HGETALL, key)
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
@@ -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
- # Read several responses from server
60
- # (see #read_response)
61
- def read_responses(n)
62
- Array.new(n) { read_response }
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
@@ -14,7 +14,7 @@ module Oxblood
14
14
  # pipeline.echo('!')
15
15
  # pipeline.sync # => ["ping", "PONG", "!"]
16
16
  class Pipeline
17
- include Oxblood::Commands
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 do |c|
30
- Oxblood::Protocol.build_command(*c)
31
- end
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
- yield Session.new(conn)
43
- ensure
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
@@ -13,7 +13,7 @@ module Oxblood
13
13
  # session = Oxblood::Session.new(conn)
14
14
  # session.ping # => 'PONG'
15
15
  class Session
16
- include Oxblood::Commands
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)
@@ -1,3 +1,3 @@
1
1
  module Oxblood
2
- VERSION = '0.1.0.dev10'
2
+ VERSION = '0.1.0.dev11'
3
3
  end
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.dev10
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: 2016-11-10 00:00:00.000000000 Z
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.7
158
+ rubygems_version: 2.6.8
159
159
  signing_key:
160
160
  specification_version: 4
161
161
  summary: A Ruby Redis client