fluffle 0.2.2 → 0.3.0

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