bones-rpc 0.0.1

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/bones-rpc.gemspec +29 -0
  10. data/lib/bones-rpc.rb +2 -0
  11. data/lib/bones/rpc.rb +23 -0
  12. data/lib/bones/rpc/adapter.rb +49 -0
  13. data/lib/bones/rpc/adapter/base.rb +41 -0
  14. data/lib/bones/rpc/adapter/erlang.rb +28 -0
  15. data/lib/bones/rpc/adapter/json.rb +23 -0
  16. data/lib/bones/rpc/adapter/msgpack.rb +52 -0
  17. data/lib/bones/rpc/adapter/parser.rb +37 -0
  18. data/lib/bones/rpc/address.rb +167 -0
  19. data/lib/bones/rpc/cluster.rb +266 -0
  20. data/lib/bones/rpc/connection.rb +146 -0
  21. data/lib/bones/rpc/connection/reader.rb +49 -0
  22. data/lib/bones/rpc/connection/socket.rb +4 -0
  23. data/lib/bones/rpc/connection/socket/connectable.rb +196 -0
  24. data/lib/bones/rpc/connection/socket/ssl.rb +35 -0
  25. data/lib/bones/rpc/connection/socket/tcp.rb +28 -0
  26. data/lib/bones/rpc/connection/writer.rb +51 -0
  27. data/lib/bones/rpc/context.rb +48 -0
  28. data/lib/bones/rpc/errors.rb +33 -0
  29. data/lib/bones/rpc/failover.rb +38 -0
  30. data/lib/bones/rpc/failover/disconnect.rb +33 -0
  31. data/lib/bones/rpc/failover/ignore.rb +31 -0
  32. data/lib/bones/rpc/failover/retry.rb +39 -0
  33. data/lib/bones/rpc/future.rb +26 -0
  34. data/lib/bones/rpc/instrumentable.rb +41 -0
  35. data/lib/bones/rpc/instrumentable/log.rb +45 -0
  36. data/lib/bones/rpc/instrumentable/noop.rb +33 -0
  37. data/lib/bones/rpc/loggable.rb +112 -0
  38. data/lib/bones/rpc/node.rb +317 -0
  39. data/lib/bones/rpc/node/registry.rb +32 -0
  40. data/lib/bones/rpc/parser.rb +114 -0
  41. data/lib/bones/rpc/parser/buffer.rb +80 -0
  42. data/lib/bones/rpc/protocol.rb +106 -0
  43. data/lib/bones/rpc/protocol/acknowledge.rb +82 -0
  44. data/lib/bones/rpc/protocol/adapter_helper.rb +164 -0
  45. data/lib/bones/rpc/protocol/binary_helper.rb +431 -0
  46. data/lib/bones/rpc/protocol/ext_message.rb +86 -0
  47. data/lib/bones/rpc/protocol/notify.rb +38 -0
  48. data/lib/bones/rpc/protocol/request.rb +45 -0
  49. data/lib/bones/rpc/protocol/response.rb +58 -0
  50. data/lib/bones/rpc/protocol/synchronize.rb +70 -0
  51. data/lib/bones/rpc/read_preference.rb +43 -0
  52. data/lib/bones/rpc/read_preference/nearest.rb +57 -0
  53. data/lib/bones/rpc/read_preference/selectable.rb +81 -0
  54. data/lib/bones/rpc/readable.rb +57 -0
  55. data/lib/bones/rpc/session.rb +195 -0
  56. data/lib/bones/rpc/uri.rb +222 -0
  57. data/lib/bones/rpc/version.rb +6 -0
  58. metadata +198 -0
@@ -0,0 +1,195 @@
1
+ # encoding: utf-8
2
+ require 'bones/rpc/read_preference'
3
+ require 'bones/rpc/readable'
4
+ require 'bones/rpc/cluster'
5
+ require 'bones/rpc/context'
6
+
7
+ module Bones
8
+ module RPC
9
+
10
+ # A session in bones_rpc is root for all interactions with a Bones::RPC server or
11
+ # replica set.
12
+ #
13
+ # It can talk to a single default database, or dynamically speak to multiple
14
+ # databases.
15
+ #
16
+ # @example Single database (console-style)
17
+ # session = Bones::RPC::Session.new(["127.0.0.1:27017"])
18
+ # session.use(:bones_rpc)
19
+ # session[:users].find.one
20
+ #
21
+ # @example Multiple databases
22
+ # session = Bones::RPC::Session.new(["127.0.0.1:27017"])
23
+ # session.with(database: :admin) do |admin|
24
+ # admin.command(ismaster: 1)
25
+ # end
26
+ #
27
+ # @example Authentication
28
+ # session = Bones::RPC::Session.new %w[127.0.0.1:27017],
29
+ # session.with(database: "admin").login("admin", "s3cr3t")
30
+ #
31
+ # @since 1.0.0
32
+ class Session
33
+ include Optionable
34
+
35
+ # @!attribute cluster
36
+ # @return [ Cluster ] The cluster of nodes.
37
+ # @!attribute options
38
+ # @return [ Hash ] The configuration options.
39
+ attr_reader :cluster, :options
40
+
41
+ # Run +command+ on the current database.
42
+ #
43
+ # @param (see Bones::RPC::Database#command)
44
+ #
45
+ # @return (see Bones::RPC::Database#command)
46
+ #
47
+ # @since 1.0.0
48
+ def command(op)
49
+ current_database.command(op)
50
+ end
51
+
52
+ def context
53
+ @context ||= Context.new(self)
54
+ end
55
+
56
+ # Disconnects all nodes in the session's cluster. This should only be used
57
+ # in cases # where you know you're not going to use the cluster on the
58
+ # thread anymore and need to force the connections to close.
59
+ #
60
+ # @return [ true ] True if the disconnect succeeded.
61
+ #
62
+ # @since 1.2.0
63
+ def disconnect
64
+ cluster.disconnect
65
+ end
66
+
67
+ def handle_refresh(node)
68
+ @callback.call(node) if @callback
69
+ end
70
+
71
+ # Provide a string inspection for the session.
72
+ #
73
+ # @example Inspect the session.
74
+ # session.inspect
75
+ #
76
+ # @return [ String ] The string inspection.
77
+ #
78
+ # @since 1.4.0
79
+ def inspect
80
+ "<#{self.class.name} seeds=#{cluster.seeds}>"
81
+ end
82
+
83
+ # Setup validation of allowed read preference options.
84
+ #
85
+ # @since 2.0.0
86
+ option(:read).allow(
87
+ :nearest
88
+ )
89
+
90
+ # Setup validation of allowed database options. (Any string or symbol)
91
+ #
92
+ # @since 2.0.0
93
+ option(:adapter).allow(Optionable.any(String), Optionable.any(Symbol), Optionable.any(Module))
94
+
95
+ # Setup validation of allowed max retry options. (Any integer)
96
+ #
97
+ # @since 2.0.0
98
+ option(:max_retries).allow(Optionable.any(Integer))
99
+
100
+ # Setup validation of allowed pool size options. (Any integer)
101
+ #
102
+ # @since 2.0.0
103
+ option(:pool_size).allow(Optionable.any(Integer))
104
+
105
+ # Setup validation of allowed retry interval options. (Any numeric)
106
+ #
107
+ # @since 2.0.0
108
+ option(:retry_interval).allow(Optionable.any(Numeric))
109
+
110
+ # Setup validation of allowed reap interval options. (Any numeric)
111
+ #
112
+ # @since 2.0.0
113
+ option(:reap_interval).allow(Optionable.any(Numeric))
114
+
115
+ # Setup validation of allowed ssl options. (Any boolean)
116
+ #
117
+ # @since 2.0.0
118
+ option(:ssl).allow(true, false)
119
+
120
+ # Setup validation of allowed timeout options. (Any numeric)
121
+ #
122
+ # @since 2.0.0
123
+ option(:timeout).allow(Optionable.any(Numeric))
124
+
125
+ # Initialize a new database session.
126
+ #
127
+ # @example Initialize a new session.
128
+ # Session.new([ "localhost:27017" ])
129
+ #
130
+ # @param [ Array ] seeds An array of host:port pairs.
131
+ # @param [ Hash ] options The options for the session.
132
+ #
133
+ # @see Above options validations for allowed values in the options hash.
134
+ #
135
+ # @since 1.0.0
136
+ def initialize(seeds, options = {}, &callback)
137
+ validate_strict(options)
138
+ @options = options
139
+ @callback = callback
140
+ @cluster = Cluster.new(self, seeds)
141
+ end
142
+
143
+ def notify(method, *params)
144
+ context.notify(method, params)
145
+ end
146
+
147
+ # Get the read preference for the session. Will default to primary if none
148
+ # was provided.
149
+ #
150
+ # @example Get the session's read preference.
151
+ # session.read_preference
152
+ #
153
+ # @return [ Object ] The read preference.
154
+ #
155
+ # @since 2.0.0
156
+ def read_preference
157
+ @read_preference ||= ReadPreference.get(options[:read] || :nearest)
158
+ end
159
+
160
+ def request(method, *params)
161
+ context.request(method, params)
162
+ end
163
+
164
+ def synchronize
165
+ context.synchronize
166
+ end
167
+
168
+ class << self
169
+
170
+ # Create a new session from a URI.
171
+ #
172
+ # @example Initialize a new session.
173
+ # Session.connect("bones-rpc://localhost:27017/my_db")
174
+ #
175
+ # @param [ String ] Bones::RPC URI formatted string.
176
+ #
177
+ # @return [ Session ] The new session.
178
+ #
179
+ # @since 3.0.0
180
+ def connect(uri, &block)
181
+ uri = Uri.new(uri)
182
+ session = new(*uri.bones_rpc_arguments, &block)
183
+ session
184
+ end
185
+ end
186
+
187
+ private
188
+
189
+ def initialize_copy(_)
190
+ @options = @options.dup
191
+ @read_preference = nil
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,222 @@
1
+ # encoding: utf-8
2
+ module Bones
3
+ module RPC
4
+
5
+ # Parses Bones::RPC uri
6
+ #
7
+ # @since 1.3.0
8
+ class Uri
9
+
10
+ # Get the scheme pattern.
11
+ #
12
+ # @since 1.3.0
13
+ SCHEME = /(bones-rpc:\/\/)/
14
+
15
+ # The user name pattern.
16
+ #
17
+ # @since 1.3.0
18
+ USER = /([-.\w:]+)/
19
+
20
+ # The password pattern.
21
+ #
22
+ # @since 1.3.0
23
+ PASS = /([^@,]+)/
24
+
25
+ # The nodes pattern.
26
+ #
27
+ # @since 1.3.0
28
+ NODES = /((([-.\w]+)(?::(\w+))?,?)+)/
29
+
30
+ # The database pattern.
31
+ #
32
+ # @since 1.3.0
33
+ DATABASE = /(?:\/([-\w]+))?/
34
+
35
+ # The options pattern.
36
+ #
37
+ # @since 1.3.0
38
+ OPTIONS = /(?:\?(.+))/
39
+
40
+ # The full URI pattern.
41
+ #
42
+ # @since 1.3.0
43
+ URI = /#{SCHEME}(#{USER}:#{PASS}@)?#{NODES}#{DATABASE}#{OPTIONS}?/
44
+
45
+ # The options that have to do with write concerns.
46
+ #
47
+ # @since 2.0.0
48
+ WRITE_OPTIONS = [ "w", "j", "fsync", "wtimeout" ].freeze
49
+
50
+ # The mappings from read preferences in the URI to Bones::RPC's.
51
+ #
52
+ # @since 2.0.0
53
+ READ_MAPPINGS = {
54
+ "nearest" => :nearest,
55
+ "primary" => :primary,
56
+ "primarypreferred" => :primary_preferred,
57
+ "secondary" => :secondary,
58
+ "secondarypreferred" => :secondary_preferred
59
+ }.freeze
60
+
61
+ # @!attribute match
62
+ # @return [ Array ] The uri match.
63
+ attr_reader :match
64
+
65
+ # Helper to determine if authentication is provided
66
+ #
67
+ # @example Boolean response if username/password given
68
+ # uri.auth_provided?
69
+ #
70
+ # @return [ true, false ] If authorization is provided.
71
+ #
72
+ # @since 1.3.0
73
+ def auth_provided?
74
+ !username.nil? && !password.nil?
75
+ end
76
+
77
+ # Get the database provided in the URI.
78
+ #
79
+ # @example Get the database.
80
+ # uri.database
81
+ #
82
+ # @return [ String ] The database.
83
+ #
84
+ # @since 1.3.0
85
+ def database
86
+ @database ||= match[9]
87
+ end
88
+
89
+ # Get the hosts provided in the URI.
90
+ #
91
+ # @example Get the hosts.
92
+ # uri.hosts
93
+ #
94
+ # @return [ Array<String> ] The hosts.
95
+ #
96
+ # @since 1.3.0
97
+ def hosts
98
+ @hosts ||= match[5].split(",")
99
+ end
100
+
101
+ # Create the new uri from the provided string.
102
+ #
103
+ # @example Create the new uri.
104
+ # Bones::RPC::Uri.new(uri)
105
+ #
106
+ # @param [ String ] string The uri string.
107
+ #
108
+ # @since 1.3.0
109
+ def initialize(string)
110
+ @match = string.match(URI)
111
+ invalid_uri!(string) unless @match
112
+ end
113
+
114
+ # Raise a human readable error when improper URI provided
115
+ #
116
+ # @example Raise error and provide guidance on invalid URI
117
+ # Bones::RPC::Uri.invalid!(uri)
118
+ #
119
+ # @param [ String ] Invalid string
120
+ #
121
+ # @since 1.3.1
122
+ def invalid_uri!(string)
123
+ scrubbed = string.gsub(/[^:]+@/, '<password>@')
124
+ raise Errors::InvalidBonesRPCURI, "The provided connection string is not a value URI: #{scrubbed}"
125
+ end
126
+
127
+ # Get the options provided in the URI.
128
+ #
129
+ # @example Get the options
130
+ # uri.options
131
+ #
132
+ # @note The options provided in the URI string must match the Bones::RPC
133
+ # specification.
134
+ #
135
+ # @return [ Hash ] Options hash usable by Moped
136
+ #
137
+ # @since 1.3.0
138
+ def options
139
+ options_string, options = match[10], {}
140
+ unless options_string.nil?
141
+ options_string.split(/\&/).each do |option_string|
142
+ key, value = option_string.split(Regexp.new('='))
143
+ if WRITE_OPTIONS.include?(key)
144
+ options[:write] = { key.to_sym => cast(value) }
145
+ elsif read = READ_MAPPINGS[value.downcase]
146
+ options[:read] = read
147
+ else
148
+ options[key.to_sym] = cast(value)
149
+ end
150
+ end
151
+ end
152
+ options
153
+ end
154
+
155
+ # Get the password provided in the URI.
156
+ #
157
+ # @example Get the password.
158
+ # uri.password
159
+ #
160
+ # @return [ String ] The password.
161
+ #
162
+ # @since 1.3.0
163
+ def password
164
+ @password ||= match[4]
165
+ end
166
+
167
+ # Get the uri as a Bones::RPC friendly configuration hash.
168
+ #
169
+ # @example Get the uri as a hash.
170
+ # uri.to_hash
171
+ #
172
+ # @return [ Hash ] The uri as options.
173
+ #
174
+ # @since 1.3.0
175
+ def to_hash
176
+ config = { database: database, hosts: hosts }
177
+ if username && password
178
+ config.merge!(username: username, password: password)
179
+ end
180
+ config
181
+ end
182
+
183
+ # Create Bones::RPC usable arguments
184
+ #
185
+ # @example Get the bones_rpc args
186
+ # uri.bones_rpc_arguments
187
+ #
188
+ # @return [ Array ] Array of arguments usable by bones_rpc
189
+ #
190
+ # @since 1.3.0
191
+ def bones_rpc_arguments
192
+ [ hosts, options ]
193
+ end
194
+
195
+ # Get the username provided in the URI.
196
+ #
197
+ # @example Get the username.
198
+ # uri.username
199
+ #
200
+ # @return [ String ] The username.
201
+ #
202
+ # @since 1.3.0
203
+ def username
204
+ @username ||= match[3]
205
+ end
206
+
207
+ private
208
+
209
+ def cast(value)
210
+ if value == "true"
211
+ true
212
+ elsif value == "false"
213
+ false
214
+ elsif value =~ /[\d]/
215
+ value.to_i
216
+ else
217
+ value.to_sym
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module Bones
3
+ module RPC
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bones-rpc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Bennett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: celluloid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: celluloid-io
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: erlang-etf
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: msgpack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: optionable
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Bones::RPC client for ruby
112
+ email:
113
+ - andrew@delorum.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .ruby-gemset
120
+ - .ruby-version
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - bones-rpc.gemspec
126
+ - lib/bones-rpc.rb
127
+ - lib/bones/rpc.rb
128
+ - lib/bones/rpc/adapter.rb
129
+ - lib/bones/rpc/adapter/base.rb
130
+ - lib/bones/rpc/adapter/erlang.rb
131
+ - lib/bones/rpc/adapter/json.rb
132
+ - lib/bones/rpc/adapter/msgpack.rb
133
+ - lib/bones/rpc/adapter/parser.rb
134
+ - lib/bones/rpc/address.rb
135
+ - lib/bones/rpc/cluster.rb
136
+ - lib/bones/rpc/connection.rb
137
+ - lib/bones/rpc/connection/reader.rb
138
+ - lib/bones/rpc/connection/socket.rb
139
+ - lib/bones/rpc/connection/socket/connectable.rb
140
+ - lib/bones/rpc/connection/socket/ssl.rb
141
+ - lib/bones/rpc/connection/socket/tcp.rb
142
+ - lib/bones/rpc/connection/writer.rb
143
+ - lib/bones/rpc/context.rb
144
+ - lib/bones/rpc/errors.rb
145
+ - lib/bones/rpc/failover.rb
146
+ - lib/bones/rpc/failover/disconnect.rb
147
+ - lib/bones/rpc/failover/ignore.rb
148
+ - lib/bones/rpc/failover/retry.rb
149
+ - lib/bones/rpc/future.rb
150
+ - lib/bones/rpc/instrumentable.rb
151
+ - lib/bones/rpc/instrumentable/log.rb
152
+ - lib/bones/rpc/instrumentable/noop.rb
153
+ - lib/bones/rpc/loggable.rb
154
+ - lib/bones/rpc/node.rb
155
+ - lib/bones/rpc/node/registry.rb
156
+ - lib/bones/rpc/parser.rb
157
+ - lib/bones/rpc/parser/buffer.rb
158
+ - lib/bones/rpc/protocol.rb
159
+ - lib/bones/rpc/protocol/acknowledge.rb
160
+ - lib/bones/rpc/protocol/adapter_helper.rb
161
+ - lib/bones/rpc/protocol/binary_helper.rb
162
+ - lib/bones/rpc/protocol/ext_message.rb
163
+ - lib/bones/rpc/protocol/notify.rb
164
+ - lib/bones/rpc/protocol/request.rb
165
+ - lib/bones/rpc/protocol/response.rb
166
+ - lib/bones/rpc/protocol/synchronize.rb
167
+ - lib/bones/rpc/read_preference.rb
168
+ - lib/bones/rpc/read_preference/nearest.rb
169
+ - lib/bones/rpc/read_preference/selectable.rb
170
+ - lib/bones/rpc/readable.rb
171
+ - lib/bones/rpc/session.rb
172
+ - lib/bones/rpc/uri.rb
173
+ - lib/bones/rpc/version.rb
174
+ homepage: ''
175
+ licenses:
176
+ - MIT
177
+ metadata: {}
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - '>='
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - '>='
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.0.5
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Bones::RPC client for ruby
198
+ test_files: []