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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3b8da3123f3885cb835b2c0800da180274aa68c
4
- data.tar.gz: d41d309e3e9f883d7bd51a0786e690cef388efcb
3
+ metadata.gz: c3cc50db4db8b982f79b85954265a191f92994b8
4
+ data.tar.gz: 3a140a07037992c73f53872a4684604b0500645c
5
5
  SHA512:
6
- metadata.gz: 19d8756d422e2b31e299c8afd6971d381af12788623997f789bea25d32b654ced753a3968195e7e38f76cb3d45766842931d1325dae926345c67f6ef29ea8fae
7
- data.tar.gz: 1ab9c2291366feec26837e91b34fd7ef07a2283331327200ad71cf01a379ad1430c7970ad020e823339603aa2b8a75b1a740f879d85a12757f49559265ac694b
6
+ metadata.gz: 433fe48debfcf3991d99d49e195de568b30f4a404b74aa6ea3a7ee6261ee2505d1d33bb713a1570eea0a526e406872a5f1588a4c2358c85e1df65ff77340419a
7
+ data.tar.gz: 73f90c97b364059f96a2bc44f84ea28d421638fe389b6547d58bcb7d8c39d4d050407ab6e810a442adfbacac5e6eb0ca54de37a77d045af396dbaf61db2612aa
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zss (0.1.0)
4
+ zss (0.2.0)
5
5
  activesupport (~> 4.1)
6
6
  daemons (~> 1.1)
7
7
  em-zeromq (~> 0.5)
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
@@ -1,4 +1,5 @@
1
1
  require 'em-zeromq'
2
+ require_relative '../zss'
2
3
  require_relative 'router'
3
4
  require_relative 'message/smi'
4
5
 
data/lib/zss/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ZSS
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -139,12 +139,12 @@ describe ZSS::Client do
139
139
  userMessage: "user info",
140
140
  developerMessage: "dev info"
141
141
  )
142
- msg.status = 500
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(500)
147
+ expect(error.code).to eq(999)
148
148
  end
149
149
  end
150
150
 
@@ -8,22 +8,74 @@ describe ZSS::Error do
8
8
 
9
9
  describe('#ctor') do
10
10
 
11
- subject do
12
- described_class.new(500, response)
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
- it('returns a fullfilled error.message') do
16
- expect(subject.code).to eq(500)
17
- expect(subject.developer_message).to eq("dev info")
18
- expect(subject.user_message).to eq("user info")
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
- it('returns error with dev info as error.message') do
22
- expect(subject.message).to eq("dev info")
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
- it('returns error with stacktrace') do
26
- expect(subject.backtrace).not_to be_nil
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.1.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-07-31 00:00:00.000000000 Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler