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 +4 -4
- data/README.md +26 -0
- data/lib/fluffle/server.rb +19 -27
- data/lib/fluffle/version.rb +1 -1
- data/spec/server_spec.rb +19 -32
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e481e4031ed4755adaf94debc3e95cf390669412
|
4
|
+
data.tar.gz: 3df471df73388ccc1dbf7b0bc5e355de381a3e17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/fluffle/server.rb
CHANGED
@@ -79,47 +79,33 @@ module Fluffle
|
|
79
79
|
def handle_request(handler:, properties:, payload:)
|
80
80
|
reply_to = properties[:reply_to]
|
81
81
|
|
82
|
-
|
82
|
+
id = nil
|
83
|
+
response = nil
|
83
84
|
|
84
85
|
begin
|
85
|
-
|
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
|
-
|
101
|
-
end
|
89
|
+
response = self.call_handler handler: handler, request: request
|
102
90
|
rescue => err
|
103
|
-
|
91
|
+
response = {
|
104
92
|
'jsonrpc' => '2.0',
|
105
|
-
'id' =>
|
93
|
+
'id' => id,
|
106
94
|
'error' => self.build_error_response(err)
|
107
95
|
}
|
108
96
|
end
|
109
97
|
|
110
|
-
|
111
|
-
|
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
|
-
|
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 = {
|
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
|
data/lib/fluffle/version.rb
CHANGED
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
|
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.
|
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-
|
11
|
+
date: 2016-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|