oxblood 0.1.0.dev10 → 0.1.0.dev11

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
  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