fluffle 0.2.2 → 0.3.0

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: 5873bf894f32f349386f18661620aabd487dabb9
4
- data.tar.gz: 6f832fa861f56d4186a7e260bbed46b0233c7428
3
+ metadata.gz: e481e4031ed4755adaf94debc3e95cf390669412
4
+ data.tar.gz: 3df471df73388ccc1dbf7b0bc5e355de381a3e17
5
5
  SHA512:
6
- metadata.gz: 59bedfeb61ff2766100e3515dbcd75f4f240cb58febb9ceb904e9a696d305e52e894fb6aef61124a852554c09ef0fee202735cb06a85e5548b2c4888ec661446
7
- data.tar.gz: 6a9bfdbc4940b1ff64a2536c9c65ed61fd36dde610a0a4cf1b9390a4bf7709f31a626179028df42ce0f3cd82f6111bf2ea7a368067cca6988df313f84a69168e
6
+ metadata.gz: b46141c7c5f0170e117db9e5bccebe3c92208ecf8c000d2dc393c01cb8c30414e0811e1dcf2c4c75971e91ec1296874d4f34eb6b415c064d190afde2cc7a51c1
7
+ data.tar.gz: fe1b05b29c37d871006aa9fce70a9367d39cbde3a76f8870b7a01a95d5a64085440d9dfafe558118549857a12918a49f61dccce194ac453be77a7faececb4e87
data/README.md CHANGED
@@ -22,6 +22,10 @@ Both the client and server implementations should be thread-safe, as their behav
22
22
 
23
23
  [concurrent-ruby]: https://github.com/ruby-concurrency/concurrent-ruby
24
24
 
25
+ **Note**: Fluffle uses JSON-RPC as a transfer format to structure requests and responses. However, due to some of the limitations imposed by AMQP, it cannot implement the complete set of behaviors in the JSON-RPC protocol. The most substantial of these limitations is that [batch requests][] are not supported.
26
+
27
+ [batch requests]: http://www.jsonrpc.org/specification#batch
28
+
25
29
  ## Examples
26
30
 
27
31
  See the [`examples`](examples/) directory.
@@ -64,6 +68,28 @@ client.call 'upcase', ['Hello world!']
64
68
  # => "HELLO WORLD!"
65
69
  ```
66
70
 
71
+ ## Response meta-data
72
+
73
+ The server adds an additional `meta` field to the response object with meta-data about how the request was handled. Currently the only entry in the `meta` object is the float `handler_duration` which is duration in seconds that was spent exclusively processing the handler.
74
+
75
+ ```javascript
76
+ // Example successful response with meta-data (6ms spent in handler)
77
+ {
78
+ "jsonrpc": "2.0",
79
+ "id": "123",
80
+ "result": "baz",
81
+ "meta": {"handler_duration": 0.006}
82
+ }
83
+
84
+ // Example error response with meta-data
85
+ {
86
+ "jsonrpc": "2.0",
87
+ "id": "123",
88
+ "error": {"code": -32601, "message": "Method not found"},
89
+ "meta": {"handler_duration": 0.007}
90
+ }
91
+ ```
92
+
67
93
  ## License
68
94
 
69
95
  Released under the MIT license, see [LICENSE](LICENSE) for details.
@@ -79,47 +79,33 @@ module Fluffle
79
79
  def handle_request(handler:, properties:, payload:)
80
80
  reply_to = properties[:reply_to]
81
81
 
82
- responses = []
82
+ id = nil
83
+ response = nil
83
84
 
84
85
  begin
85
- decoded = self.decode payload
86
-
87
- requests =
88
- if decoded.is_a? Hash
89
- [ decoded ] # Single request
90
- elsif decoded.is_a? Array
91
- decoded # Batch request
92
- else
93
- raise Errors::InvalidRequestError.new('Payload was neither an Array nor an Object')
94
- end
95
-
96
- requests.each do |request|
97
- response = self.call_handler handler: handler,
98
- request: request
86
+ request = self.decode payload
87
+ id = request['id']
99
88
 
100
- responses << response
101
- end
89
+ response = self.call_handler handler: handler, request: request
102
90
  rescue => err
103
- responses << {
91
+ response = {
104
92
  'jsonrpc' => '2.0',
105
- 'id' => nil,
93
+ 'id' => id,
106
94
  'error' => self.build_error_response(err)
107
95
  }
108
96
  end
109
97
 
110
- responses.each do |response|
111
- @exchange.publish Oj.dump(response), routing_key: reply_to,
112
- correlation_id: response['id']
113
- end
98
+ @exchange.publish Oj.dump(response), routing_key: reply_to,
99
+ correlation_id: response['id']
114
100
  end
115
101
 
116
102
  # handler - Instance of a `Handler` that may receive `#call`
117
103
  # request - `Hash` representing a decoded Request
118
104
  def call_handler(handler:, request:)
105
+ t0 = Time.now
106
+
119
107
  begin
120
- # We don't yet know if it's valid, so we have to be as cautious as
121
- # possible about getting the ID
122
- id = begin request['id']; rescue; nil end
108
+ id = request['id']
123
109
 
124
110
  self.validate_request request
125
111
 
@@ -133,7 +119,13 @@ module Fluffle
133
119
  error = self.build_error_response err
134
120
  end
135
121
 
136
- response = { 'jsonrpc' => '2.0', 'id' => id }
122
+ response = {
123
+ 'jsonrpc' => '2.0',
124
+ 'id' => id,
125
+ 'meta' => {
126
+ 'handler_duration' => (Time.now - t0)
127
+ }
128
+ }
137
129
 
138
130
  if error
139
131
  response['error'] = error
@@ -1,3 +1,3 @@
1
1
  module Fluffle
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.0'
3
3
  end
data/spec/server_spec.rb CHANGED
@@ -49,7 +49,7 @@ describe Fluffle::Server do
49
49
  payload['id'] ||= id
50
50
 
51
51
  expect(@exchange_spy).to have_received(:publish) do |payload_json, opts|
52
- expect(Oj.load(payload_json)).to eq payload
52
+ expect(Oj.load(payload_json)).to include payload
53
53
 
54
54
  expect(opts).to eq routing_key: routing_key,
55
55
  correlation_id: correlation_id
@@ -78,37 +78,6 @@ describe Fluffle::Server do
78
78
  expect_response payload: { 'result' => result }
79
79
  end
80
80
 
81
- it 'responds with the correct individual results for a batch request' do
82
- payload = [
83
- { 'jsonrpc' => '2.0', 'id' => 'first', 'method' => 'multiply', 'params' => [1] },
84
- { 'jsonrpc' => '2.0', 'id' => 'second', 'method' => 'multiply', 'params' => [2] }
85
- ]
86
-
87
- handler = double 'Handler'
88
- expect(handler).to receive(:call).twice do |args|
89
- expect(args).to include({
90
- id: anything,
91
- method: 'multiply'
92
- })
93
-
94
- args[:params].first * 2
95
- end
96
-
97
- responses = []
98
-
99
- allow(@exchange_spy).to receive(:publish).ordered do |payload_json, _opts|
100
- responses << Oj.load(payload_json)
101
- end
102
-
103
- subject.handle_request handler: handler,
104
- properties: { reply_to: reply_to },
105
- payload: Oj.dump(payload)
106
-
107
- expect(responses.length).to eq 2
108
- expect(responses[0]).to include('id' => 'first', 'result' => 2)
109
- expect(responses[1]).to include('id' => 'second', 'result' => 4)
110
- end
111
-
112
81
  it 'responds with the appropriate code and message when method not found' do
113
82
  @method = 'notfound'
114
83
 
@@ -141,5 +110,23 @@ describe Fluffle::Server do
141
110
  }
142
111
  }
143
112
  end
113
+
114
+ it 'includes appropriate meta-data in the response' do
115
+ handler = double 'Handler'
116
+ expect(handler).to receive(:call) do |args|
117
+ sleep 0.01
118
+
119
+ 'Hello world!'
120
+ end
121
+
122
+ make_request handler: handler
123
+
124
+ expect(@exchange_spy).to have_received(:publish) do |payload_json, opts|
125
+ payload = Oj.load payload_json
126
+ meta = payload['meta']
127
+
128
+ expect(meta['handler_duration']).to be >= 0.01
129
+ end
130
+ end
144
131
  end
145
132
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluffle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dirk Gadsden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-17 00:00:00.000000000 Z
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny