carrot_rpc 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +31 -14
- data/CODE_OF_CONDUCT.md +8 -0
- data/Gemfile +0 -1
- data/README.md +22 -5
- data/carrot_rpc.gemspec +1 -1
- data/circle.yml +9 -2
- data/lib/carrot_rpc/client_server.rb +24 -1
- data/lib/carrot_rpc/exception.rb +1 -0
- data/lib/carrot_rpc/hash_extensions.rb +5 -3
- data/lib/carrot_rpc/rpc_client.rb +28 -3
- data/lib/carrot_rpc/rpc_server.rb +6 -2
- data/lib/carrot_rpc/version.rb +2 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ba255fb6d2e277988ef84326c30193fe9dc0ca7
|
4
|
+
data.tar.gz: 7c8a26c482a1041887f7ac73eb5bd9396966a3fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca9b37d0788166fe678d7281cfeac3846f662370b6a5ac6de02fc3567df59ddce010999f61555603ba7c0170f338ee5f32a9d70e7e7f71f2bc86e0cac7bf358b
|
7
|
+
data.tar.gz: 71d2becd5fa8dab667c8b82c3e98e194c29cd46ab95d1997304597aa929741cb2a7287fdb936d46d991c160e06642fde18b504953c868e628329a71fb8d9ad7e
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,52 +3,69 @@
|
|
3
3
|
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
4
4
|
|
5
5
|
- [Changelog](#changelog)
|
6
|
+
- [v1.0.0](#v100)
|
7
|
+
- [Incompatible Changes](#incompatible-changes)
|
8
|
+
- [v0.8.1](#v081)
|
9
|
+
- [Enhancements](#enhancements)
|
10
|
+
- [v0.8.0](#v080)
|
11
|
+
- [Enhancements](#enhancements-1)
|
6
12
|
- [v0.7.1](#v071)
|
7
13
|
- [Bug Fixes](#bug-fixes)
|
8
14
|
- [v0.7.0](#v070)
|
9
15
|
- [Bug Fixes](#bug-fixes-1)
|
10
|
-
- [Incompatible Changes](#incompatible-changes)
|
16
|
+
- [Incompatible Changes](#incompatible-changes-1)
|
11
17
|
- [v0.6.0](#v060)
|
12
|
-
- [Enhancements](#enhancements)
|
18
|
+
- [Enhancements](#enhancements-2)
|
13
19
|
- [v0.5.1](#v051)
|
14
20
|
- [Bug Fixes](#bug-fixes-2)
|
15
21
|
- [v0.5.0](#v050)
|
16
|
-
- [Enhancements](#enhancements-
|
17
|
-
- [Incompatible Changes](#incompatible-changes-
|
22
|
+
- [Enhancements](#enhancements-3)
|
23
|
+
- [Incompatible Changes](#incompatible-changes-2)
|
18
24
|
- [v0.4.1](#v041)
|
19
25
|
- [Bug Fixes](#bug-fixes-3)
|
20
26
|
- [v0.4.0](#v040)
|
21
|
-
- [Enhancements](#enhancements-
|
27
|
+
- [Enhancements](#enhancements-4)
|
22
28
|
- [Bug Fixes](#bug-fixes-4)
|
23
|
-
- [Incompatible Changes](#incompatible-changes-
|
29
|
+
- [Incompatible Changes](#incompatible-changes-3)
|
24
30
|
- [v0.3.0](#v030)
|
25
|
-
- [Enhancements](#enhancements-
|
31
|
+
- [Enhancements](#enhancements-5)
|
26
32
|
- [Bug Fixes](#bug-fixes-5)
|
27
33
|
- [v0.2.3](#v023)
|
28
|
-
- [Enhancements](#enhancements-
|
34
|
+
- [Enhancements](#enhancements-6)
|
29
35
|
- [Bug Fixes](#bug-fixes-6)
|
30
36
|
- [Upgrading](#upgrading)
|
31
37
|
- [v0.2.1](#v021)
|
32
38
|
- [Bug Fixes](#bug-fixes-7)
|
33
39
|
- [v0.2.0](#v020)
|
34
|
-
- [Enhancements](#enhancements-
|
40
|
+
- [Enhancements](#enhancements-7)
|
35
41
|
- [Bug Fixes](#bug-fixes-8)
|
36
|
-
- [Incompatible Changes](#incompatible-changes-
|
42
|
+
- [Incompatible Changes](#incompatible-changes-4)
|
37
43
|
- [v0.1.2](#v012)
|
38
|
-
- [Enhancements](#enhancements-
|
44
|
+
- [Enhancements](#enhancements-8)
|
39
45
|
- [Bug Fixes](#bug-fixes-9)
|
40
46
|
- [v0.1.1](#v011)
|
41
|
-
- [Enhancements](#enhancements-
|
47
|
+
- [Enhancements](#enhancements-9)
|
42
48
|
- [Bug Fixes](#bug-fixes-10)
|
43
|
-
- [Incompatible Changes](#incompatible-changes-
|
49
|
+
- [Incompatible Changes](#incompatible-changes-5)
|
44
50
|
|
45
51
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
46
52
|
|
47
53
|
# Changelog
|
48
54
|
All significant changes in the project are documented here.
|
49
55
|
|
56
|
+
## v1.0.0
|
57
|
+
### Incompatible Changes
|
58
|
+
* [#48](https://github.com/C-S-D/carrot_rpc/pull/48) - Remove queue for correlation_id when RpcClient#wait_for_result raises an exception. -[@nward](https://github.com/nward)
|
59
|
+
* [#50](https://github.com/C-S-D/carrot_rpc/pull/50) - Raise an exception for error responses to let consuming application handle response. -[@nward](https://github.com/nward)
|
60
|
+
* [#52](https://github.com/C-S-D/carrot_rpc/pull/52) - Allow custom queue options to be set -[@nward](https://github.com/nward)
|
61
|
+
* [#53](https://github.com/C-S-D/carrot_rpc/pull/53) - Rename keys for any hashes inside arrays. Fixes issue [#35](https://github.com/C-S-D/carrot_rpc/issues/35) -[@thewalkingtoast](https://github.com/thewalkingtoast)
|
62
|
+
|
63
|
+
## v0.8.1
|
64
|
+
### Enhancements
|
65
|
+
* Update to Ruby 2.2.6 and have tests run for Ruby 2.3 and 2.4.
|
66
|
+
|
50
67
|
## v0.8.0
|
51
|
-
###
|
68
|
+
### Enhancements
|
52
69
|
* Don't assume that Bunny already has a connection to RabbitMQ.
|
53
70
|
* Attempt to start Bunny for the servers
|
54
71
|
* This allows the implementing application to decide when to start the connection when using a forking web server
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
2
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
3
|
+
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
4
|
+
|
5
|
+
- [Contributor Code of Conduct](#contributor-code-of-conduct)
|
6
|
+
|
7
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
8
|
+
|
1
9
|
|
2
10
|
# Contributor Code of Conduct
|
3
11
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,8 @@
|
|
11
11
|
- [Writing Servers](#writing-servers)
|
12
12
|
- [Writing Clients](#writing-clients)
|
13
13
|
- [Using request threading in clients](#using-request-threading-in-clients)
|
14
|
+
- [Custom Queue Options](#custom-queue-options)
|
15
|
+
- [Errors](#errors)
|
14
16
|
- [Support for JSONAPI::Resources](#support-for-jsonapiresources)
|
15
17
|
- [Development](#development)
|
16
18
|
- [Contributing](#contributing)
|
@@ -249,6 +251,21 @@ class ProfileClient < CarrotRpc::RpcClient
|
|
249
251
|
end
|
250
252
|
```
|
251
253
|
|
254
|
+
### Custom Queue Options
|
255
|
+
By default, client queues are defined with `auto_delete: false`, and server queues are defined with no parameters, so use the Bunny/RabbitMQ defaults. These can be customised by calling the `queue_options` class method to add to or override these options on either a RpcClient or RpcServer subclass. This method takes any queue parameter accepted by Bunny.
|
256
|
+
Care should be taken when setting these options, as CarrotRPC does not attempt to fix mistakes here. The defaults are typically what you want.
|
257
|
+
|
258
|
+
The following overrides the default CarrotRpc auto_delete option, and sets durable to true:
|
259
|
+
```ruby
|
260
|
+
class CarClient < CarrotRpc::RpcClient
|
261
|
+
queue_name "car_queue"
|
262
|
+
queue_options auto_delete: true, durable: true
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
266
|
+
#### Errors
|
267
|
+
If a JSON-RPC error is returned, a CarrotRpc::Error exception is raised with the appropriate attributes set. If a malformed JSON-RPC error is returned (i.e. code or message are missing), an CarrotRpc::Exception::InvalidResponse exception is raised.
|
268
|
+
|
252
269
|
### Support for JSONAPI::Resources
|
253
270
|
In the case that you're writing an application that uses the `jsonapi-resources` gem and you want the `RpcServer` to have the same functionality, then we got you covered. All you need to do is import a few modules. See [jsonapi-resources](https://github.com/cerebris/jsonapi-resources) for details on how to implement resources for your models.
|
254
271
|
|
@@ -257,25 +274,25 @@ Example Server with JSONAPI functionality:
|
|
257
274
|
class CarServer < CarrotRpc::RpcServer
|
258
275
|
extend CarrotRpc::RpcServer::JSONAPIResources::Actions
|
259
276
|
include CarrotRpc::RpcServer::JSONAPIResources
|
260
|
-
|
277
|
+
|
261
278
|
# declare the actions to enable
|
262
279
|
actions: :create, :destroy, :index, :show, :update
|
263
|
-
|
280
|
+
|
264
281
|
# Context so it can build urls
|
265
282
|
def base_url
|
266
283
|
"http://foo.com"
|
267
284
|
end
|
268
|
-
|
285
|
+
|
269
286
|
# Context to find the resource and create links.
|
270
287
|
def controller
|
271
288
|
"api/cars"
|
272
289
|
end
|
273
|
-
|
290
|
+
|
274
291
|
# JSONAPI::Resource example: `app/resources/car_resource.rb`
|
275
292
|
def resource_klass
|
276
293
|
CarResource
|
277
294
|
end
|
278
|
-
|
295
|
+
|
279
296
|
queue_name "car_queue"
|
280
297
|
|
281
298
|
def show(params)
|
data/carrot_rpc.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
# Production requirements
|
29
29
|
|
30
30
|
# Common extensions from Rails
|
31
|
-
spec.add_dependency "activesupport", "
|
31
|
+
spec.add_dependency "activesupport", ">= 4.2", "< 6.x"
|
32
32
|
# The RabbitMQ library
|
33
33
|
spec.add_dependency "bunny", "~> 2.2"
|
34
34
|
|
data/circle.yml
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
machine:
|
2
2
|
services:
|
3
3
|
- rabbitmq-server
|
4
|
+
dependencies:
|
5
|
+
override:
|
6
|
+
- 'rvm-exec 2.2.6 bundle install'
|
7
|
+
- 'rvm-exec 2.3.3 bundle install'
|
8
|
+
- 'rvm-exec 2.4.0 bundle install'
|
4
9
|
test:
|
5
10
|
override:
|
6
|
-
- RAILS_ENV=test bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml
|
11
|
+
- 'RAILS_ENV=test rvm-exec 2.2.6 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
|
12
|
+
- 'RAILS_ENV=test rvm-exec 2.3.3 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
|
13
|
+
- 'RAILS_ENV=test rvm-exec 2.4.0 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
|
7
14
|
post:
|
8
|
-
- bundle exec rubocop
|
15
|
+
- 'rvm-exec 2.2.6 bundle exec rubocop'
|
@@ -19,7 +19,30 @@ module CarrotRpc::ClientServer
|
|
19
19
|
@queue_name = args[0]
|
20
20
|
else
|
21
21
|
fail ArgumentError,
|
22
|
-
"queue_name(new_name) :: new_name or queue_name() ::
|
22
|
+
"queue_name(new_name) :: new_name or queue_name() :: " \
|
23
|
+
"current_name are the only ways to call queue_name"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @overload queue_options(options)
|
28
|
+
#
|
29
|
+
# Allows for custom queue options, such as durable.
|
30
|
+
#
|
31
|
+
# @options params [Hash] a hash of options to pass to bunny.
|
32
|
+
#
|
33
|
+
# @overload queue_options
|
34
|
+
# The current queue options previously set with `#queue_options(options)`.
|
35
|
+
#
|
36
|
+
# @return [Hash]
|
37
|
+
def queue_options(*args)
|
38
|
+
if args.length == 0
|
39
|
+
@queue_options || {}
|
40
|
+
elsif args.length == 1
|
41
|
+
@queue_options = args[0]
|
42
|
+
else
|
43
|
+
fail ArgumentError,
|
44
|
+
"queue_options(options) :: options or queue_options() :: " \
|
45
|
+
"current_options are the only ways to call queue_options"
|
23
46
|
end
|
24
47
|
end
|
25
48
|
|
data/lib/carrot_rpc/exception.rb
CHANGED
@@ -5,11 +5,13 @@ module CarrotRpc::HashExtensions
|
|
5
5
|
# @param [String] find the text to look for in a keys
|
6
6
|
# @param [String] replace the text to replace the found text
|
7
7
|
# @return [Hash] a new hash
|
8
|
-
def rename_keys(find, replace, new_hash = {})
|
8
|
+
def rename_keys(find, replace, new_hash = {}) # rubocop:disable Metrics/MethodLength
|
9
9
|
each do |k, v|
|
10
10
|
new_key = k.to_s.gsub(find, replace)
|
11
11
|
|
12
|
-
new_hash[new_key] = if v.is_a?
|
12
|
+
new_hash[new_key] = if v.is_a? Array
|
13
|
+
v.map { |t| t.rename_keys(find, replace) }
|
14
|
+
elsif v.is_a? Hash
|
13
15
|
v.rename_keys(find, replace)
|
14
16
|
else
|
15
17
|
v
|
@@ -17,6 +19,6 @@ module CarrotRpc::HashExtensions
|
|
17
19
|
end
|
18
20
|
|
19
21
|
new_hash
|
20
|
-
end
|
22
|
+
end # rubocop:enable Metrics/MethodLength
|
21
23
|
end
|
22
24
|
end
|
@@ -40,7 +40,8 @@ class CarrotRpc::RpcClient
|
|
40
40
|
|
41
41
|
queue_name = self.class.test_queue_name(self.class.queue_name, @config.client_test_mode)
|
42
42
|
# auto_delete => false keeps the queue around until RabbitMQ restarts or explicitly deleted
|
43
|
-
|
43
|
+
options = { auto_delete: false }.merge(self.class.queue_options)
|
44
|
+
@server_queue = @channel.queue(queue_name, options)
|
44
45
|
|
45
46
|
# Setup a direct exchange.
|
46
47
|
@exchange = @channel.default_exchange
|
@@ -87,10 +88,16 @@ class CarrotRpc::RpcClient
|
|
87
88
|
# and this must happend before the `Hash.delete` or
|
88
89
|
# the receiving thread won't be able to find the correlation_id in @results
|
89
90
|
result = @results[correlation_id].pop
|
90
|
-
|
91
|
+
|
92
|
+
# If we get an exception, raise it in this thread, so the application can deal with it.
|
93
|
+
if result.is_a? Exception
|
94
|
+
fail result
|
95
|
+
end
|
96
|
+
|
91
97
|
result
|
92
98
|
end
|
93
99
|
ensure
|
100
|
+
@results.delete correlation_id # remove item from hash. prevents memory leak.
|
94
101
|
@channel.close
|
95
102
|
end
|
96
103
|
|
@@ -151,12 +158,30 @@ class CarrotRpc::RpcClient
|
|
151
158
|
response[:result]
|
152
159
|
# data is the key holding the error information
|
153
160
|
elsif response.key?(:error)
|
154
|
-
response
|
161
|
+
parse_error_result(response)
|
155
162
|
else
|
156
163
|
response
|
157
164
|
end
|
158
165
|
end
|
159
166
|
|
167
|
+
# Build an CarrotRpc::Error based on an error response or throw CarrotRpc::Exception::InvalidResponse if
|
168
|
+
# the response error itself is invalid.
|
169
|
+
# @param [Hash] response from rpc call
|
170
|
+
# @return [CarrotRpc::Error, CarrotRpc::Exception::InvalidResponse]
|
171
|
+
def parse_error_result(response)
|
172
|
+
# If we don't have a code, throw an exception.
|
173
|
+
unless response[:error].key?(:code) &&
|
174
|
+
response[:error].key?(:message)
|
175
|
+
return CarrotRpc::Exception::InvalidResponse.new
|
176
|
+
end
|
177
|
+
|
178
|
+
CarrotRpc::Error.new(
|
179
|
+
code: response[:error][:code],
|
180
|
+
data: response[:error].key?(:data) ? response[:error][:data] : nil,
|
181
|
+
message: response[:error][:message]
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
160
185
|
def publish_payload(payload, correlation_id:)
|
161
186
|
# Reply To => make sure the service knows where to send it's response.
|
162
187
|
# Correlation ID => identify the results that belong to the unique call made
|
@@ -18,8 +18,7 @@ class CarrotRpc::RpcServer
|
|
18
18
|
@channel = config.bunny.create_channel
|
19
19
|
@logger = config.logger
|
20
20
|
@block = block
|
21
|
-
|
22
|
-
@server_queue = @channel.queue(queue_name)
|
21
|
+
setup_queue(config)
|
23
22
|
@exchange = @channel.default_exchange
|
24
23
|
end
|
25
24
|
|
@@ -92,6 +91,11 @@ class CarrotRpc::RpcServer
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
94
|
+
def setup_queue(config)
|
95
|
+
queue_name = self.class.test_queue_name(self.class.queue_name, config.server_test_mode)
|
96
|
+
@server_queue = @channel.queue(queue_name, self.class.queue_options)
|
97
|
+
end
|
98
|
+
|
95
99
|
def thread_request(request_message:)
|
96
100
|
logger.debug "Threading request (#{request_message.inspect}) " \
|
97
101
|
"in Thread.current.thread_variable_get(#{thread_request_variable.inspect})"
|
data/lib/carrot_rpc/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrot_rpc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Hamilton
|
@@ -9,22 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '4.2'
|
21
|
+
- - "<"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 6.x
|
21
24
|
type: :runtime
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
|
-
- - "
|
28
|
+
- - ">="
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: '4.2'
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 6.x
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
35
|
name: bunny
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|