zss 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +191 -0
- data/lib/zss/client.rb +2 -1
- data/lib/zss/error.rb +12 -2
- data/lib/zss/service.rb +1 -0
- data/lib/zss/version.rb +1 -1
- data/spec/unit/client_spec.rb +2 -2
- data/spec/unit/error_spec.rb +62 -10
- 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: c3cc50db4db8b982f79b85954265a191f92994b8
|
4
|
+
data.tar.gz: 3a140a07037992c73f53872a4684604b0500645c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 433fe48debfcf3991d99d49e195de568b30f4a404b74aa6ea3a7ee6261ee2505d1d33bb713a1570eea0a526e406872a5f1588a4c2358c85e1df65ff77340419a
|
7
|
+
data.tar.gz: 73f90c97b364059f96a2bc44f84ea28d421638fe389b6547d58bcb7d8c39d4d050407ab6e810a442adfbacac5e6eb0ca54de37a77d045af396dbaf61db2612aa
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -67,6 +67,197 @@ PongClient.call("ping/pong", "payload")
|
|
67
67
|
|
68
68
|
```
|
69
69
|
|
70
|
+
### Client errors
|
71
|
+
|
72
|
+
The client raises services errors using ZSS::Error class, with code, developer message and user message.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require 'zss'
|
76
|
+
|
77
|
+
PongClient = ZSS::Client.new(:pong)
|
78
|
+
|
79
|
+
begin
|
80
|
+
PongClient.ping("payload")
|
81
|
+
rescue ZSS::Error => error
|
82
|
+
puts "Status code: #{error.code}"
|
83
|
+
puts "User Message: #{error.user_message}"
|
84
|
+
puts "Developer Message: #{error.developer_message}"
|
85
|
+
end
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
## ZSS Service
|
90
|
+
|
91
|
+
The ZSS Service is responsible for receiving ZSS Request and execute configured service handlers.
|
92
|
+
|
93
|
+
**The main components are:**
|
94
|
+
* ZSS::Service.new(:sid, config)
|
95
|
+
|
96
|
+
This component responsible for receiving and routing ZSS requests.
|
97
|
+
The first parameter is service identifier (sid), you can use either symbol or string.
|
98
|
+
The configuration parameter will be used to pass heartbeat interval and broker backend address.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
config = {
|
102
|
+
backend: 'tcp://127.0.0.1:7776', # default: tcp://127.0.0.1:7776
|
103
|
+
heartbeat: 1000 # ms, default: 1s
|
104
|
+
}
|
105
|
+
service = ZSS::Service.new(:pong, config)
|
106
|
+
```
|
107
|
+
|
108
|
+
* ZSS::Runner.run(:sid)
|
109
|
+
|
110
|
+
This component is responsible to execute a ZSS::Service as daemon, when in background it redirects stdout to file and manages pid files. It uses [daemon gem](https://rubygems.org/gems/daemon).
|
111
|
+
|
112
|
+
$ bin/pong run
|
113
|
+
|
114
|
+
or in background, where pidfile and logs are under /log
|
115
|
+
|
116
|
+
$ bin/pong start/stop
|
117
|
+
|
118
|
+
* ZSS::ServiceRegister
|
119
|
+
|
120
|
+
This component is the glue entry point between Runner & Service.
|
121
|
+
|
122
|
+
|
123
|
+
**NOTE:** You can run services without using the runner and service register, they are just one way to run services, you can use your own. Using Runner and service registry all services are done on the same way and using shared infra.
|
124
|
+
|
125
|
+
### Creating a new service step by step
|
126
|
+
|
127
|
+
Let's create our first service sample, Ping-Pong, step by step.
|
128
|
+
Note: For your next services you will be able to use [Service Generation rake](#zss-service-generation-rake), but for now you learn what the rake does and why!
|
129
|
+
|
130
|
+
* Create you service logic class, adding a pong_service.rb under /lib folder.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
class PongService
|
134
|
+
|
135
|
+
# it print's payload and headers on the console
|
136
|
+
def ping(payload, headers)
|
137
|
+
puts "Payload => #{payload}"
|
138
|
+
puts "Headers => #{headers}"
|
139
|
+
|
140
|
+
return "PONG"
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
```
|
146
|
+
**NOTE:** Headers parameter is optional!
|
147
|
+
|
148
|
+
* Create the service registration, adding a service_register.rb under /lib folder.
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
module ZSS
|
152
|
+
class ServiceRegister
|
153
|
+
|
154
|
+
def self.get_service
|
155
|
+
config = Hashie::Mash.new(
|
156
|
+
# this data should be received from a config file instead!
|
157
|
+
backend: 'tcp://127.0.0.1:7776'
|
158
|
+
)
|
159
|
+
|
160
|
+
# create a service instance for sid :pong
|
161
|
+
service = ZSS::Service.new(:pong, config)
|
162
|
+
|
163
|
+
instance = PongService.new
|
164
|
+
# register route ping for the service
|
165
|
+
service.add_route(instance, :ping)
|
166
|
+
|
167
|
+
service
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
```
|
173
|
+
|
174
|
+
* Hook your files by creating start.rb under /lib folder.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
require 'zss/service'
|
178
|
+
|
179
|
+
require_relative 'service_register'
|
180
|
+
require_relative 'pong_service'
|
181
|
+
```
|
182
|
+
|
183
|
+
* Register LoggerFacade plugin/s
|
184
|
+
|
185
|
+
The ZSS library uses the [LoggerFacade](https://github.com/pjanuario/logger-facade-ruby) library to abstract logging info, so you should hook your plugins on start.rb.
|
186
|
+
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
# log level should be retrieved from a configuration file
|
190
|
+
plugin = LoggerFacade::Plugins::Console.new({ level: :debug })
|
191
|
+
LoggerFacade::Manager.use(plugin)
|
192
|
+
```
|
193
|
+
|
194
|
+
* Create a binary file to run the service as daemon, such as bin/pong
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
#!/usr/bin/env ruby
|
198
|
+
require 'rubygems' unless defined?(Gem)
|
199
|
+
|
200
|
+
require 'bundler/setup'
|
201
|
+
Bundler.require
|
202
|
+
|
203
|
+
$env = ENV['ZSS_ENV'] || 'development'
|
204
|
+
|
205
|
+
require 'zss/runner'
|
206
|
+
require_relative '../lib/start'
|
207
|
+
|
208
|
+
# Runner receives the identifier used for pid and log filename
|
209
|
+
ZSS::Runner.run(:pong)
|
210
|
+
```
|
211
|
+
|
212
|
+
**NOTES:**
|
213
|
+
* ZSS_ENV: is used to identify the running environment
|
214
|
+
|
215
|
+
|
216
|
+
You running service example [here](https://github.com/pjanuario/zss-service-sample)
|
217
|
+
|
218
|
+
### Returning errors
|
219
|
+
|
220
|
+
Every exception that is raised by the service is shield and result on a response with status code 500 with default user and developer messages.
|
221
|
+
|
222
|
+
The available errors dictionary is defined in [error.json](https://github.com/pjanuario/zmq-service-suite-ruby/blob/master/lib/zss/errors.json).
|
223
|
+
|
224
|
+
**Raising different errors**
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
raise Error[500]
|
228
|
+
# or
|
229
|
+
raise Error.new
|
230
|
+
# or
|
231
|
+
raise Error.new(500)
|
232
|
+
# or with developer message override
|
233
|
+
raise Error.new(500, "this message should helpfull for developer!")
|
234
|
+
```
|
235
|
+
When relevant errors should be raised be with developer messages!
|
236
|
+
|
237
|
+
**New Error Types**
|
238
|
+
|
239
|
+
New error types should be added to [error.json](https://github.com/pjanuario/zmq-service-suite-ruby/blob/master/lib/zss/errors.json) using pull request.
|
240
|
+
|
241
|
+
|
242
|
+
### ZSS Service Generation Rake
|
243
|
+
|
244
|
+
[**#TODO**](https://github.com/pjanuario/zmq-service-suite-ruby/issues/11)
|
245
|
+
|
246
|
+
rake zss:service sid (--airbrake)
|
247
|
+
|
248
|
+
It generates the service skeleton, adding several files into root directory:
|
249
|
+
* sid - binary file named with sid
|
250
|
+
* start.rb with console plugin attached (--airbrake will add Airbrake plugin also)
|
251
|
+
* sid_service.rb
|
252
|
+
* service_register.rb
|
253
|
+
* config/application.yml
|
254
|
+
* travis.yml
|
255
|
+
* .rvmrc.sample
|
256
|
+
* .rvmrc
|
257
|
+
* .rspec
|
258
|
+
* Gemfile
|
259
|
+
* .gitignore
|
260
|
+
|
70
261
|
## Contributing
|
71
262
|
|
72
263
|
1. Fork it
|
data/lib/zss/client.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../zss'
|
1
2
|
require_relative 'socket'
|
2
3
|
|
3
4
|
module ZSS
|
@@ -29,7 +30,7 @@ module ZSS
|
|
29
30
|
|
30
31
|
log.info("Received response to #{request.rid} with status #{response.status}")
|
31
32
|
|
32
|
-
fail ZSS::Error.new(response.status, response.payload) if response.is_error?
|
33
|
+
fail ZSS::Error.new(response.status, payload: response.payload) if response.is_error?
|
33
34
|
|
34
35
|
response.payload
|
35
36
|
end
|
data/lib/zss/error.rb
CHANGED
@@ -6,9 +6,19 @@ module ZSS
|
|
6
6
|
attr_reader :code, :user_message
|
7
7
|
attr_accessor :developer_message
|
8
8
|
|
9
|
-
def initialize(code, payload)
|
9
|
+
def initialize(code = 500, developer_message = nil, payload: nil)
|
10
|
+
|
11
|
+
if payload
|
12
|
+
fail "Invalid error code: #{code}" if code.blank?
|
13
|
+
else
|
14
|
+
data = self.class.get_errors[code.to_s]
|
15
|
+
payload = data.body if data
|
16
|
+
end
|
17
|
+
|
18
|
+
fail "Invalid error with code: #{code}" unless payload
|
19
|
+
|
10
20
|
@code = code.to_i
|
11
|
-
@developer_message = payload.developerMessage
|
21
|
+
@developer_message = developer_message || payload.developerMessage
|
12
22
|
@user_message = payload.userMessage
|
13
23
|
super @developer_message
|
14
24
|
set_backtrace caller
|
data/lib/zss/service.rb
CHANGED
data/lib/zss/version.rb
CHANGED
data/spec/unit/client_spec.rb
CHANGED
@@ -139,12 +139,12 @@ describe ZSS::Client do
|
|
139
139
|
userMessage: "user info",
|
140
140
|
developerMessage: "dev info"
|
141
141
|
)
|
142
|
-
msg.status =
|
142
|
+
msg.status = 999
|
143
143
|
msg
|
144
144
|
end
|
145
145
|
|
146
146
|
expect { subject.call(:ping, "ping") }.to raise_exception(ZSS::Error) do |error|
|
147
|
-
expect(error.code).to eq(
|
147
|
+
expect(error.code).to eq(999)
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
data/spec/unit/error_spec.rb
CHANGED
@@ -8,22 +8,74 @@ describe ZSS::Error do
|
|
8
8
|
|
9
9
|
describe('#ctor') do
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
context('on invalid code') do
|
12
|
+
|
13
|
+
it('raises an exception when code is nil') do
|
14
|
+
expect{ described_class.new(nil, payload: response) }.to raise_exception(RuntimeError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it('raises an exception when code does not exist on errors.json') do
|
18
|
+
expect{ described_class.new(0) }.to raise_exception(RuntimeError)
|
19
|
+
end
|
20
|
+
|
13
21
|
end
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
context('with payload') do
|
24
|
+
|
25
|
+
subject do
|
26
|
+
described_class.new(500, payload: response)
|
27
|
+
end
|
28
|
+
|
29
|
+
it('returns a fullfilled error.message') do
|
30
|
+
expect(subject.code).to eq(500)
|
31
|
+
expect(subject.developer_message).to eq("dev info")
|
32
|
+
expect(subject.user_message).to eq("user info")
|
33
|
+
end
|
34
|
+
|
35
|
+
it('returns error with dev info as error.message') do
|
36
|
+
expect(subject.message).to eq("dev info")
|
37
|
+
end
|
38
|
+
|
39
|
+
it('returns error with stacktrace') do
|
40
|
+
expect(subject.backtrace).not_to be_nil
|
41
|
+
end
|
42
|
+
|
19
43
|
end
|
20
44
|
|
21
|
-
|
22
|
-
|
45
|
+
context('with default error') do
|
46
|
+
|
47
|
+
subject { described_class.new }
|
48
|
+
|
49
|
+
it('returns an error') do
|
50
|
+
expect(subject.code).to eq(500)
|
51
|
+
expect(subject.developer_message).not_to be_nil
|
52
|
+
expect(subject.user_message).not_to be_nil
|
53
|
+
end
|
54
|
+
|
23
55
|
end
|
24
56
|
|
25
|
-
|
26
|
-
|
57
|
+
|
58
|
+
context('with default error') do
|
59
|
+
|
60
|
+
subject { described_class.new(500) }
|
61
|
+
|
62
|
+
it('returns an error') do
|
63
|
+
expect(subject.code).to eq(500)
|
64
|
+
expect(subject.developer_message).not_to be_nil
|
65
|
+
expect(subject.user_message).not_to be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
context('with override on developer message') do
|
70
|
+
|
71
|
+
subject { described_class.new(500, "dev info") }
|
72
|
+
|
73
|
+
it('returns an error') do
|
74
|
+
expect(subject.code).to eq(500)
|
75
|
+
expect(subject.developer_message).to eq('dev info')
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
27
79
|
end
|
28
80
|
|
29
81
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Januário
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|