bones-rpc 0.0.2 → 0.0.3

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-gemset +1 -1
  3. data/.ruby-version +1 -1
  4. data/bones-rpc.gemspec +1 -4
  5. data/lib/bones/rpc.rb +1 -1
  6. data/lib/bones/rpc/adapter.rb +44 -4
  7. data/lib/bones/rpc/adapter/json.rb +66 -0
  8. data/lib/bones/rpc/address.rb +6 -4
  9. data/lib/bones/rpc/backend.rb +31 -0
  10. data/lib/bones/rpc/backend/base.rb +30 -0
  11. data/lib/bones/rpc/backend/synchronous.rb +29 -0
  12. data/lib/bones/rpc/cluster.rb +18 -18
  13. data/lib/bones/rpc/connection.rb +19 -15
  14. data/lib/bones/rpc/connection/socket.rb +0 -2
  15. data/lib/bones/rpc/connection/socket/connectable.rb +15 -11
  16. data/lib/bones/rpc/context.rb +2 -2
  17. data/lib/bones/rpc/dns_resolver.rb +85 -0
  18. data/lib/bones/rpc/errors.rb +3 -0
  19. data/lib/bones/rpc/failover.rb +3 -3
  20. data/lib/bones/rpc/failover/disconnect.rb +2 -2
  21. data/lib/bones/rpc/failover/ignore.rb +2 -2
  22. data/lib/bones/rpc/failover/retry.rb +2 -2
  23. data/lib/bones/rpc/instrumentable.rb +3 -3
  24. data/lib/bones/rpc/instrumentable/log.rb +2 -2
  25. data/lib/bones/rpc/instrumentable/noop.rb +2 -2
  26. data/lib/bones/rpc/loggable.rb +8 -8
  27. data/lib/bones/rpc/node.rb +47 -37
  28. data/lib/bones/rpc/node/registry.rb +4 -0
  29. data/lib/bones/rpc/parser.rb +16 -5
  30. data/lib/bones/rpc/parser/buffer.rb +6 -2
  31. data/lib/bones/rpc/protocol/adapter_helper.rb +2 -2
  32. data/lib/bones/rpc/protocol/binary_helper.rb +2 -2
  33. data/lib/bones/rpc/read_preference.rb +3 -3
  34. data/lib/bones/rpc/read_preference/nearest.rb +3 -3
  35. data/lib/bones/rpc/read_preference/selectable.rb +4 -4
  36. data/lib/bones/rpc/readable.rb +4 -4
  37. data/lib/bones/rpc/session.rb +25 -16
  38. data/lib/bones/rpc/synchronous.rb +2 -0
  39. data/lib/bones/rpc/synchronous/connection.rb +36 -0
  40. data/lib/bones/rpc/synchronous/connection/reader.rb +59 -0
  41. data/lib/bones/rpc/synchronous/connection/socket.rb +4 -0
  42. data/lib/bones/rpc/synchronous/connection/socket/ssl.rb +57 -0
  43. data/lib/bones/rpc/synchronous/connection/socket/tcp.rb +30 -0
  44. data/lib/bones/rpc/synchronous/connection/writer.rb +86 -0
  45. data/lib/bones/rpc/synchronous/future.rb +91 -0
  46. data/lib/bones/rpc/synchronous/node.rb +45 -0
  47. data/lib/bones/rpc/uri.rb +20 -20
  48. data/lib/bones/rpc/version.rb +1 -1
  49. metadata +16 -52
  50. data/lib/bones/rpc/adapter/erlang.rb +0 -28
  51. data/lib/bones/rpc/adapter/msgpack.rb +0 -52
  52. data/lib/bones/rpc/connection/reader.rb +0 -49
  53. data/lib/bones/rpc/connection/socket/ssl.rb +0 -35
  54. data/lib/bones/rpc/connection/socket/tcp.rb +0 -28
  55. data/lib/bones/rpc/connection/writer.rb +0 -51
  56. data/lib/bones/rpc/future.rb +0 -26
@@ -6,7 +6,7 @@ module Bones
6
6
  # Provides the shared behaviour for read preferences that can filter by a
7
7
  # tag set or add query options.
8
8
  #
9
- # @since 2.0.0
9
+ # @since 0.0.1
10
10
  module Selectable
11
11
 
12
12
  # @!attribute tags
@@ -20,7 +20,7 @@ module Bones
20
20
  #
21
21
  # @param [ Array<Hash> ] tags The tag sets.
22
22
  #
23
- # @since 2.0.0
23
+ # @since 0.0.1
24
24
  def initialize(tags = nil)
25
25
  @tags = tags
26
26
  end
@@ -34,7 +34,7 @@ module Bones
34
34
  #
35
35
  # @return [ Hash ] The options plus additional query options.
36
36
  #
37
- # @since 2.0.0
37
+ # @since 0.0.1
38
38
  def query_options(options)
39
39
  options[:flags] ||= []
40
40
  options[:flags] |= [ :slave_ok ]
@@ -60,7 +60,7 @@ module Bones
60
60
  #
61
61
  # @return [ Object ] The result of the block.
62
62
  #
63
- # @since 2.0.0
63
+ # @since 0.0.1
64
64
  def with_retry(cluster, retries = cluster.max_retries, &block)
65
65
  begin
66
66
  block.call
@@ -4,7 +4,7 @@ module Bones
4
4
 
5
5
  # Provides behaviour around readable objects.
6
6
  #
7
- # @since 2.0.0
7
+ # @since 0.0.1
8
8
  module Readable
9
9
 
10
10
  private
@@ -18,7 +18,7 @@ module Bones
18
18
  #
19
19
  # @return [ Cluster ] The cluster.
20
20
  #
21
- # @since 2.0.0
21
+ # @since 0.0.1
22
22
  def cluster
23
23
  session.cluster
24
24
  end
@@ -32,7 +32,7 @@ module Bones
32
32
  #
33
33
  # @return [ Object ] The session's read preference.
34
34
  #
35
- # @since 2.0.0
35
+ # @since 0.0.1
36
36
  def read_preference
37
37
  session.read_preference
38
38
  end
@@ -48,7 +48,7 @@ module Bones
48
48
  #
49
49
  # @return [ Hash ] The new query options.
50
50
  #
51
- # @since 2.0.0
51
+ # @since 0.0.1
52
52
  def query_options(options = {})
53
53
  read_preference.query_options(options)
54
54
  end
@@ -28,7 +28,7 @@ module Bones
28
28
  # session = Bones::RPC::Session.new %w[127.0.0.1:27017],
29
29
  # session.with(database: "admin").login("admin", "s3cr3t")
30
30
  #
31
- # @since 1.0.0
31
+ # @since 0.0.1
32
32
  class Session
33
33
  include Optionable
34
34
 
@@ -38,13 +38,17 @@ module Bones
38
38
  # @return [ Hash ] The configuration options.
39
39
  attr_reader :cluster, :options
40
40
 
41
+ def backend
42
+ @backend ||= Backend.get(options[:backend] || :synchronous).tap(&:setup)
43
+ end
44
+
41
45
  # Run +command+ on the current database.
42
46
  #
43
47
  # @param (see Bones::RPC::Database#command)
44
48
  #
45
49
  # @return (see Bones::RPC::Database#command)
46
50
  #
47
- # @since 1.0.0
51
+ # @since 0.0.1
48
52
  def command(op)
49
53
  current_database.command(op)
50
54
  end
@@ -59,7 +63,7 @@ module Bones
59
63
  #
60
64
  # @return [ true ] True if the disconnect succeeded.
61
65
  #
62
- # @since 1.2.0
66
+ # @since 0.0.1
63
67
  def disconnect
64
68
  cluster.disconnect
65
69
  end
@@ -75,51 +79,56 @@ module Bones
75
79
  #
76
80
  # @return [ String ] The string inspection.
77
81
  #
78
- # @since 1.4.0
82
+ # @since 0.0.1
79
83
  def inspect
80
84
  "<#{self.class.name} seeds=#{cluster.seeds}>"
81
85
  end
82
86
 
83
87
  # Setup validation of allowed read preference options.
84
88
  #
85
- # @since 2.0.0
89
+ # @since 0.0.1
86
90
  option(:read).allow(
87
91
  :nearest
88
92
  )
89
93
 
90
- # Setup validation of allowed database options. (Any string or symbol)
94
+ # Setup validation of allowed adapter options. (Any string or symbol)
91
95
  #
92
- # @since 2.0.0
96
+ # @since 0.0.1
93
97
  option(:adapter).allow(Optionable.any(String), Optionable.any(Symbol), Optionable.any(Module))
94
98
 
99
+ # Setup validation of allowed backend options, (Any string or symbol)
100
+ #
101
+ # @since 0.0.1
102
+ option(:backend).allow(Optionable.any(String), Optionable.any(Symbol), Optionable.any(Module))
103
+
95
104
  # Setup validation of allowed max retry options. (Any integer)
96
105
  #
97
- # @since 2.0.0
106
+ # @since 0.0.1
98
107
  option(:max_retries).allow(Optionable.any(Integer))
99
108
 
100
109
  # Setup validation of allowed pool size options. (Any integer)
101
110
  #
102
- # @since 2.0.0
111
+ # @since 0.0.1
103
112
  option(:pool_size).allow(Optionable.any(Integer))
104
113
 
105
114
  # Setup validation of allowed retry interval options. (Any numeric)
106
115
  #
107
- # @since 2.0.0
116
+ # @since 0.0.1
108
117
  option(:retry_interval).allow(Optionable.any(Numeric))
109
118
 
110
119
  # Setup validation of allowed reap interval options. (Any numeric)
111
120
  #
112
- # @since 2.0.0
121
+ # @since 0.0.1
113
122
  option(:reap_interval).allow(Optionable.any(Numeric))
114
123
 
115
124
  # Setup validation of allowed ssl options. (Any boolean)
116
125
  #
117
- # @since 2.0.0
126
+ # @since 0.0.1
118
127
  option(:ssl).allow(true, false)
119
128
 
120
129
  # Setup validation of allowed timeout options. (Any numeric)
121
130
  #
122
- # @since 2.0.0
131
+ # @since 0.0.1
123
132
  option(:timeout).allow(Optionable.any(Numeric))
124
133
 
125
134
  # Initialize a new database session.
@@ -132,7 +141,7 @@ module Bones
132
141
  #
133
142
  # @see Above options validations for allowed values in the options hash.
134
143
  #
135
- # @since 1.0.0
144
+ # @since 0.0.1
136
145
  def initialize(seeds, options = {}, &callback)
137
146
  validate_strict(options)
138
147
  @options = options
@@ -152,7 +161,7 @@ module Bones
152
161
  #
153
162
  # @return [ Object ] The read preference.
154
163
  #
155
- # @since 2.0.0
164
+ # @since 0.0.1
156
165
  def read_preference
157
166
  @read_preference ||= ReadPreference.get(options[:read] || :nearest)
158
167
  end
@@ -176,7 +185,7 @@ module Bones
176
185
  #
177
186
  # @return [ Session ] The new session.
178
187
  #
179
- # @since 3.0.0
188
+ # @since 0.0.1
180
189
  def connect(uri, &block)
181
190
  uri = Uri.new(uri)
182
191
  session = new(*uri.bones_rpc_arguments, &block)
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'bones/rpc/synchronous/node'
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require 'bones/rpc/connection'
3
+ require 'monitor'
4
+
5
+ module Bones
6
+ module RPC
7
+ module Synchronous
8
+
9
+ # This class contains behaviour of Bones::RPC socket connections.
10
+ #
11
+ # @since 0.0.1
12
+ class Connection < ::Bones::RPC::Connection
13
+
14
+ require 'bones/rpc/synchronous/connection/reader'
15
+ require 'bones/rpc/synchronous/connection/socket'
16
+ require 'bones/rpc/synchronous/connection/writer'
17
+
18
+ writer_class ::Bones::RPC::Synchronous::Connection::Writer
19
+
20
+ def write(operations)
21
+ with_connection do |socket|
22
+ proxy = writer.write(operations)
23
+ if proxy
24
+ Timeout::timeout(timeout) do
25
+ while not proxy.registry_empty?
26
+ writer.reader.read(proxy)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ module Bones
3
+ module RPC
4
+ module Synchronous
5
+ class Connection
6
+ class Reader
7
+ def initialize(connection, socket, adapter, writer)
8
+ @connection = connection
9
+ @socket = socket
10
+ @adapter = adapter
11
+ @writer = writer
12
+ @alive = true
13
+ @buffer = ""
14
+ end
15
+
16
+ def alive?
17
+ !!@alive
18
+ end
19
+
20
+ def parse(data, proxy)
21
+ @buffer << data
22
+ if @buffer.empty?
23
+ read(proxy)
24
+ else
25
+ parser = Bones::RPC::Parser.new(@buffer, @adapter)
26
+ begin
27
+ loop { send parser.read, proxy }
28
+ rescue EOFError
29
+ @buffer.replace(parser.buffer.to_str)
30
+ end
31
+ return if @buffer.empty?
32
+ read(proxy)
33
+ end
34
+ end
35
+
36
+ def read(proxy)
37
+ parse @socket.readpartial(4096), proxy
38
+ rescue EOFError, Errors::ConnectionFailure => e
39
+ Loggable.warn(" BONES-RPC:", "#{@connection.node.address.resolved} Reader terminating: #{e.message}", "n/a")
40
+ terminate
41
+ raise e
42
+ end
43
+
44
+ def send(message, proxy)
45
+ proxy.handle_message(message)
46
+ end
47
+
48
+ def terminate
49
+ return if not alive?
50
+ @alive = false
51
+ @buffer.clear
52
+ @writer.terminate
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ require 'bones/rpc/connection/socket'
3
+ require 'bones/rpc/synchronous/connection/socket/ssl'
4
+ require 'bones/rpc/synchronous/connection/socket/tcp'
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ require 'openssl'
3
+
4
+ module Bones
5
+ module RPC
6
+ module Synchronous
7
+ class Connection
8
+ module Socket
9
+
10
+ # This is a wrapper around a tcp socket.
11
+ class SSL < ::OpenSSL::SSL::SSLSocket
12
+ include ::Bones::RPC::Connection::Socket::Connectable
13
+
14
+ attr_reader :socket
15
+
16
+ # Initialize the new TCPSocket with SSL.
17
+ #
18
+ # @example Initialize the socket.
19
+ # SSL.new("127.0.0.1", 27017)
20
+ #
21
+ # @param [ String ] host The host.
22
+ # @param [ Integer ] port The port.
23
+ #
24
+ # @since 0.0.1
25
+ def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
26
+ @host, @port = remote_host.to_s, remote_port
27
+ handle_socket_errors do
28
+ @socket = TCPSocket.new(@host, remote_port, local_host, local_port)
29
+ super(socket)
30
+ self.sync_close = true
31
+ connect
32
+ end
33
+ end
34
+
35
+ # Set the encoding of the underlying socket.
36
+ #
37
+ # @param [ String ] string The encoding.
38
+ #
39
+ # @since 0.0.1
40
+ def set_encoding(string)
41
+ socket.set_encoding(string)
42
+ end
43
+
44
+ # Set a socket option on the underlying socket.
45
+ #
46
+ # @param [ Array<Object> ] args The option arguments.
47
+ #
48
+ # @since 0.0.1
49
+ def setsockopt(*args)
50
+ socket.setsockopt(*args)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ module Bones
3
+ module RPC
4
+ module Synchronous
5
+ class Connection
6
+ module Socket
7
+
8
+ # This is a wrapper around a tcp socket.
9
+ class TCP < ::TCPSocket
10
+ include ::Bones::RPC::Connection::Socket::Connectable
11
+
12
+ # Initialize the new TCPSocket.
13
+ #
14
+ # @example Initialize the socket.
15
+ # TCP.new("127.0.0.1", 27017)
16
+ #
17
+ # @param [ String ] remote_host The host.
18
+ # @param [ Integer ] remote_port The port.
19
+ #
20
+ # @since 0.0.1
21
+ def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
22
+ @host, @port = remote_host.to_s, remote_port
23
+ handle_socket_errors { super(@host, port, local_host, local_port) }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ module Bones
3
+ module RPC
4
+ module Synchronous
5
+ class Connection
6
+ class Writer
7
+ attr_reader :reader
8
+
9
+ def initialize(connection, socket, adapter)
10
+ @connection = connection
11
+ @socket = socket
12
+ @adapter = adapter
13
+ @resolved = @connection.node.address.resolved
14
+ @alive = true
15
+ @buffer = ""
16
+ @reader = Reader.new(@connection, @socket, @adapter, self)
17
+ end
18
+
19
+ def alive?
20
+ !!@alive
21
+ end
22
+
23
+ def async
24
+ self
25
+ end
26
+
27
+ def write(operations)
28
+ proxy = NodeProxy.new(@connection.node)
29
+ operations.each do |message, future|
30
+ message.serialize(@buffer, @adapter)
31
+ message.attach(proxy, future) if future
32
+ end
33
+ @socket.write(@buffer)
34
+ @buffer = ""
35
+ return proxy
36
+ rescue EOFError, Errors::ConnectionFailure => e
37
+ Loggable.warn(" BONES-RPC:", "#{@resolved} Writer terminating: #{e.message}", "n/a")
38
+ terminate
39
+ raise e
40
+ end
41
+
42
+ def terminate
43
+ return if not alive?
44
+ @alive = false
45
+ @reader.terminate
46
+ @connection.cleanup_socket(@socket)
47
+ end
48
+
49
+ class NodeProxy < ::BasicObject
50
+ def attach(channel, id, future)
51
+ @registry.set(channel, id, future)
52
+ end
53
+
54
+ def detach(channel, id)
55
+ @registry.get(channel, id)
56
+ end
57
+
58
+ def handle_message(message)
59
+ logging(message) do
60
+ if future = message.get(self)
61
+ message.signal(future)
62
+ end
63
+ end
64
+ end
65
+
66
+ def initialize(node)
67
+ @node = node
68
+ @registry = Node::Registry.new
69
+ end
70
+
71
+ def registry_empty?
72
+ @registry.empty?
73
+ end
74
+
75
+ protected
76
+
77
+ def method_missing(name, *args, &block)
78
+ @node.__send__(name, *args, &block)
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end