zss 0.2.5 → 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: b6209d59b210fc8bd7e64ed36f5fca6642c40f61
4
- data.tar.gz: cf82318a2842a97b3d8ac7199e665b29820a6eaa
3
+ metadata.gz: 9929b5eec2008f17870d5526121bb9b7d8dfacac
4
+ data.tar.gz: e47be6ad965a97fa60328e19391f6291eb8e864c
5
5
  SHA512:
6
- metadata.gz: eee1a5348aae779968829771172d51b8c085e328816f8317b253984b5c565227522d4c05c39aa3d60e56c4533efdad04661a9b3ef81bdfb3130cc674dfc05193
7
- data.tar.gz: 3939c3e70096ce5f5ecfe47a72b986c21a8202d970ceb189b97cfda6a68c35c01cb35044b259fae882b1c9520778320c8a63fab560bf931ba3c435b014ea7f64
6
+ metadata.gz: 77bceb3312a63f02956010f946a4925d49361e099f2d41654f55f143f42df1d7f37ae897ea2aa4f133eba6beb4165421d43d50542a1883f7da5d0ebf16344bb9
7
+ data.tar.gz: 898068c75ef33bfae1551acfb874b4aad33775f7860996d195adf8768d4ce48b022066f5cf0c1b60ff2b6ee49f6d09f1d91d3c3b9364626376188e49ff87df72
@@ -1,19 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zss (0.2.5)
5
- activesupport (~> 4.1)
4
+ zss (0.3.0)
5
+ activesupport (= 4.1)
6
6
  daemons (~> 1.1)
7
7
  em-zeromq (~> 0.5)
8
8
  ffi-rzmq (~> 2.0)
9
9
  hashie (~> 3.2)
10
- logger_facade (~> 0.1)
10
+ logger_facade (~> 0.3.2)
11
11
  msgpack (~> 0.5)
12
12
 
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
- activesupport (4.1.6)
16
+ activesupport (4.1.0)
17
17
  i18n (~> 0.6, >= 0.6.9)
18
18
  json (~> 1.7, >= 1.7.7)
19
19
  minitest (~> 5.1)
@@ -23,10 +23,10 @@ GEM
23
23
  builder
24
24
  multi_json
25
25
  builder (3.2.2)
26
- bump (0.5.0)
27
- celluloid (0.15.2)
28
- timers (~> 1.1.0)
29
- codeclimate-test-reporter (0.3.0)
26
+ bump (0.5.1)
27
+ celluloid (0.16.0)
28
+ timers (~> 4.0.0)
29
+ codeclimate-test-reporter (0.4.5)
30
30
  simplecov (>= 0.7.1, < 1.0.0)
31
31
  coderay (1.1.0)
32
32
  daemons (1.1.9)
@@ -36,52 +36,56 @@ GEM
36
36
  eventmachine (>= 1.0.0)
37
37
  ffi (>= 1.0.0)
38
38
  ffi-rzmq (~> 2.0.1)
39
- eventmachine (1.0.3)
40
- ffi (1.9.3)
39
+ eventmachine (1.0.4)
40
+ ffi (1.9.6)
41
41
  ffi-rzmq (2.0.1)
42
42
  ffi-rzmq-core (>= 1.0.1)
43
43
  ffi-rzmq-core (1.0.3)
44
44
  ffi (~> 1.9)
45
- hashie (3.3.1)
46
- i18n (0.6.11)
47
- json (1.8.1)
48
- logger_facade (0.2.0)
45
+ hashie (3.3.2)
46
+ hitimes (1.2.2)
47
+ i18n (0.7.0)
48
+ json (1.8.2)
49
+ logger_facade (0.3.2)
49
50
  airbrake (~> 4.0)
50
51
  hashie (~> 3.2)
51
52
  sucker_punch (~> 1.1)
53
+ yajl-ruby (~> 1.2)
52
54
  method_source (0.8.2)
53
- minitest (5.4.2)
54
- msgpack (0.5.8)
55
+ minitest (5.5.1)
56
+ msgpack (0.5.10)
55
57
  multi_json (1.10.1)
56
- pry (0.10.0)
58
+ pry (0.10.1)
57
59
  coderay (~> 1.1.0)
58
60
  method_source (~> 0.8.1)
59
61
  slop (~> 3.4)
60
- rake (10.3.2)
61
- rspec (3.0.0)
62
- rspec-core (~> 3.0.0)
63
- rspec-expectations (~> 3.0.0)
64
- rspec-mocks (~> 3.0.0)
65
- rspec-core (3.0.3)
66
- rspec-support (~> 3.0.0)
67
- rspec-expectations (3.0.3)
62
+ rake (10.4.2)
63
+ rspec (3.1.0)
64
+ rspec-core (~> 3.1.0)
65
+ rspec-expectations (~> 3.1.0)
66
+ rspec-mocks (~> 3.1.0)
67
+ rspec-core (3.1.7)
68
+ rspec-support (~> 3.1.0)
69
+ rspec-expectations (3.1.2)
68
70
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.0.0)
70
- rspec-mocks (3.0.3)
71
- rspec-support (~> 3.0.0)
72
- rspec-support (3.0.3)
73
- simplecov (0.9.0)
71
+ rspec-support (~> 3.1.0)
72
+ rspec-mocks (3.1.3)
73
+ rspec-support (~> 3.1.0)
74
+ rspec-support (3.1.2)
75
+ simplecov (0.9.1)
74
76
  docile (~> 1.1.0)
75
- multi_json
77
+ multi_json (~> 1.0)
76
78
  simplecov-html (~> 0.8.0)
77
79
  simplecov-html (0.8.0)
78
80
  slop (3.6.0)
79
- sucker_punch (1.2.1)
80
- celluloid (~> 0.15.2)
81
+ sucker_punch (1.3.2)
82
+ celluloid (~> 0.16.0)
81
83
  thread_safe (0.3.4)
82
- timers (1.1.0)
84
+ timers (4.0.1)
85
+ hitimes
83
86
  tzinfo (1.2.2)
84
87
  thread_safe (~> 0.1)
88
+ yajl-ruby (1.2.1)
85
89
 
86
90
  PLATFORMS
87
91
  ruby
data/README.md CHANGED
@@ -272,15 +272,15 @@ We use [bump gem](https://github.com/gregorym/bump) to control gem versioning.
272
272
 
273
273
  Bump Patch version
274
274
 
275
- $ bump patch
275
+ $ bump patch --tag
276
276
 
277
277
  Bump Minor version
278
278
 
279
- $ bump minor
279
+ $ bump minor --tag
280
280
 
281
281
  Bump Major version
282
282
 
283
- $ bump major
283
+ $ bump major --tag
284
284
 
285
285
  ## Running Specs
286
286
 
@@ -13,6 +13,11 @@ module ZSS
13
13
  @sid = sid.to_s.upcase
14
14
  @identity = config[:identity] || "client"
15
15
  @timeout = config[:timeout] || 1000
16
+ @config = Hashie::Mash.new(
17
+ socket_address: frontend,
18
+ identity: identity,
19
+ timeout: timeout
20
+ )
16
21
  end
17
22
 
18
23
  def call verb, payload, headers: {}, timeout: nil
@@ -24,11 +29,14 @@ module ZSS
24
29
  headers: headers,
25
30
  payload: payload)
26
31
 
27
- log.info("Request #{request.rid} sent to #{request.address} with #{timeout}s timeout")
32
+ timeout ||= config.timeout
33
+ metadata = metadata(timeout, request)
34
+ log.info("Request #{request.rid} sent to #{request.address} with #{timeout/1000.0}s timeout", metadata)
28
35
 
29
36
  response = socket.call(request, timeout)
37
+ metadata = metadata(timeout, response)
30
38
 
31
- log.info("Received response to #{request.rid} with status #{response.status}")
39
+ log.info("Received response to #{request.rid} with status #{response.status}", metadata)
32
40
 
33
41
  fail ZSS::Error.new(response.status, payload: response.payload) if response.is_error?
34
42
 
@@ -37,6 +45,8 @@ module ZSS
37
45
 
38
46
  private
39
47
 
48
+ attr_reader :config
49
+
40
50
  def method_missing method, *args
41
51
  # since we cannot use / on method names we replace _ with /
42
52
  verb = method.to_s.gsub('_', '/')
@@ -46,14 +56,18 @@ module ZSS
46
56
  end
47
57
 
48
58
  def socket
49
- config = Hashie::Mash.new(
50
- socket_address: frontend,
51
- identity: identity,
52
- timeout: timeout
53
- )
54
-
55
59
  Socket.new config
56
60
  end
57
61
 
62
+ def metadata(timeout, message)
63
+ metadata = {
64
+ identity: identity,
65
+ timeout: timeout,
66
+ pid: Process.pid,
67
+ request: message.to_log
68
+ }
69
+ metadata
70
+ end
71
+
58
72
  end
59
73
  end
@@ -7,16 +7,20 @@ require_relative 'message/message_address'
7
7
  module ZSS
8
8
  class Message
9
9
 
10
+ CLIENT_ID_REGEX = /^(.+?)#/
11
+
10
12
  PROTOCOL_VERSION = "ZSS:0.0"
11
13
 
12
- attr_accessor :identity,
14
+ attr_accessor :client,
15
+ :identity,
13
16
  :protocol,
14
17
  :type,
15
18
  :rid,
16
19
  :address,
17
20
  :headers,
18
21
  :status,
19
- :payload
22
+ :payload,
23
+ :payload_size
20
24
 
21
25
  def initialize(args = {})
22
26
 
@@ -28,7 +32,17 @@ module ZSS
28
32
  @headers = args[:headers] || {}
29
33
  @status = args[:status]
30
34
  @payload = args[:payload]
35
+ @client = nil
36
+ @payload_size = args[:payload_size]
37
+
38
+ match = identity.try(:match, CLIENT_ID_REGEX)
39
+ @client = match.captures.first if match
40
+ end
31
41
 
42
+ def payload=(payload)
43
+ @payload = payload
44
+ @payload_msgpack_data = nil
45
+ @payload_size = payload_msgpack.length
32
46
  end
33
47
 
34
48
  def req?
@@ -39,6 +53,11 @@ module ZSS
39
53
 
40
54
  frames.unshift(nil) if frames.length == 7
41
55
 
56
+ payload_data = frames[7]
57
+ payload_size = payload_data.length
58
+ payload = MessagePack.unpack(payload_data)
59
+ payload = Hashie::Mash.new(payload) if payload.kind_of? Hash
60
+
42
61
  msg = Message.new(
43
62
  identity: frames.shift,
44
63
  protocol: frames.shift,
@@ -49,13 +68,10 @@ module ZSS
49
68
  ),
50
69
  headers: Hashie::Mash.new(MessagePack.unpack(frames.shift)),
51
70
  status: frames.shift.to_i,
52
- payload: MessagePack.unpack(frames.shift),
71
+ payload: payload,
72
+ payload_size: payload_size
53
73
  )
54
74
 
55
- if msg.payload.kind_of? Hash
56
- msg.payload = Hashie::Mash.new(msg.payload)
57
- end
58
-
59
75
  msg
60
76
  end
61
77
 
@@ -91,13 +107,38 @@ module ZSS
91
107
  address.instance_values.to_msgpack,
92
108
  headers.to_h.to_msgpack,
93
109
  status.to_s,
94
- payload.to_msgpack
110
+ payload_msgpack
95
111
  ]
96
112
  end
97
113
 
114
+ def to_log
115
+ {
116
+ client: client,
117
+ identity: identity,
118
+ protocol: protocol,
119
+ type: type,
120
+ rid: rid,
121
+ address: address,
122
+ headers: headers,
123
+ status: status,
124
+ payload: big? ? "<<Message to big to log>>" : payload,
125
+ "payload-size" => payload_size
126
+ }
127
+ end
128
+
98
129
  def is_error?
99
130
  status != 200
100
131
  end
101
132
 
133
+ def big?
134
+ payload_size = payload_msgpack.length unless payload_size
135
+ payload_size > 1024
136
+ end
137
+
138
+ def payload_msgpack
139
+ # this will avoid executing multiple serializations
140
+ @payload_msgpack_data ||= payload.to_msgpack
141
+ end
142
+
102
143
  end
103
144
  end
@@ -28,19 +28,7 @@ module ZSS
28
28
  fail RuntimeError, 'failed to create create_context' unless context
29
29
 
30
30
  log.info("Starting SID: '#{sid}' ID: '#{identity}' Env: '#{ZSS::Environment.env}' Broker: '#{backend}'")
31
-
32
- EM.run do
33
- # handle interrupts
34
- Signal.trap("INT") { stop }
35
- Signal.trap("TERM") { stop }
36
-
37
- connect_socket context
38
-
39
- start_heartbeat_worker
40
-
41
- # send up message
42
- send Message::SMI.up(sid)
43
- end
31
+ event_machine_start(context)
44
32
  end
45
33
 
46
34
  def add_route(context, route, handler = nil)
@@ -52,7 +40,7 @@ module ZSS
52
40
 
53
41
  EM.add_timer do
54
42
 
55
- log.info("Stoping SID: '#{sid}' ID: '#{socket.identity}'")
43
+ log.info("Stoping SID: '#{sid}' ID: '#{identity}'", metadata)
56
44
 
57
45
  send Message::SMI.down(sid)
58
46
  socket.disconnect backend
@@ -64,6 +52,24 @@ module ZSS
64
52
 
65
53
  attr_accessor :socket, :router, :timer
66
54
 
55
+ def event_machine_start(context)
56
+ EM.run do
57
+ handle_interrupts
58
+
59
+ connect_socket context
60
+
61
+ start_heartbeat_worker
62
+
63
+ # send up message
64
+ send Message::SMI.up(sid)
65
+ end
66
+ end
67
+
68
+ def handle_interrupts
69
+ Signal.trap("INT") { stop }
70
+ Signal.trap("TERM") { stop }
71
+ end
72
+
67
73
  def connect_socket(context)
68
74
 
69
75
  @socket = context.socket ZMQ::DEALER
@@ -97,29 +103,31 @@ module ZSS
97
103
  if message.req?
98
104
  handle_request(message)
99
105
  else
100
- log.trace("SMI response received: \n #{message}") if log.is_debug
106
+ context = request_metadata(message)
107
+ log.trace("SMI response received: \n #{message}", context) if log.is_debug
101
108
  end
102
109
  rescue ZSS::Error => error
103
- log.error("ZSS::Error raised while processing request: #{error}")
110
+ log.error("ZSS::Error raised while processing request: #{error}", metadata({ error: error }))
104
111
  reply_error error, message
105
112
  rescue => e
106
- log.error("Unexpected error occurred while processing request: #{e}")
113
+ log.error("Unexpected error occurred while processing request: #{e}", metadata({ exception: e }))
107
114
  reply_error Error[500], message
108
115
  end
109
116
 
110
117
  def handle_request(message)
111
- log.info("Handle request for #{message.address}")
112
- log.debug("Request message:\n #{message}") if log.is_debug
118
+ start_time = Time.now.utc
113
119
 
114
- if message.address.sid != sid
115
- error = Error[404]
116
- error.developer_message = "Invalid SID: #{message.address.sid}!"
117
- fail error
118
- end
120
+ log.info("Handle request for #{message.address}", request_metadata(message))
121
+ log.trace("Request message:\n #{message}") if log.is_debug
122
+
123
+ check_sid!(message.address.sid)
119
124
 
120
125
  # the router returns an handler that receives payload and headers
121
126
  handler = router.get(message.address.verb)
127
+
122
128
  message.payload = handler.call(message.payload, message.headers)
129
+ message.headers["zss-response-time"] = get_time(start_time)
130
+
123
131
  reply message
124
132
  end
125
133
 
@@ -131,6 +139,9 @@ module ZSS
131
139
  developerMessage: error.developer_message
132
140
  }
133
141
  message.type = Message::Type::REP
142
+
143
+ log.info("Reply with status: #{message.status}", request_metadata(message))
144
+
134
145
  send message
135
146
  end
136
147
 
@@ -138,8 +149,8 @@ module ZSS
138
149
  message.status = 200
139
150
  message.type = Message::Type::REP
140
151
 
141
- log.info("Reply with status: #{message.status}")
142
- log.debug("Reply with message:\n #{message}") if log.is_debug
152
+ log.info("Reply with status: #{message.status}", request_metadata(message))
153
+ log.trace("Reply with message:\n #{message}") if log.is_debug
143
154
 
144
155
  send message
145
156
  end
@@ -151,8 +162,36 @@ module ZSS
151
162
  #remove identity frame on request
152
163
  frames.shift if msg.req?
153
164
  success = socket.send_msg(*frames)
154
- log.error("An Error ocurred while sending message") unless success
165
+
166
+ log.error("An Error ocurred while sending message", request_metadata(message)) unless success
155
167
  end
156
168
 
169
+ def check_sid!(message_sid)
170
+ return unless message_sid != sid
171
+
172
+ error = Error[404]
173
+ error.developer_message = "Invalid SID: #{message_sid}!"
174
+ fail error
175
+ end
176
+
177
+ def metadata(metadata = {})
178
+ metadata ||= {}
179
+ metadata[:sid] = sid
180
+ metadata[:identity] = identity
181
+ metadata[:pid] = Process.pid
182
+ metadata
183
+ end
184
+
185
+ def request_metadata(message, metadata = {})
186
+ metadata = metadata(metadata)
187
+
188
+ metadata[:request] = message.to_log
189
+ metadata
190
+ end
191
+
192
+ def get_time(start_time)
193
+ # return time in ms
194
+ ((Time.now.utc - start_time) * 1_000).to_i
195
+ end
157
196
  end
158
197
  end
@@ -27,16 +27,16 @@ module ZSS
27
27
  socket ctx do |sock|
28
28
  begin
29
29
  ::Timeout.timeout t do
30
-
31
- log.debug("Request #{request.rid} sent to #{request.address} with #{t}s timeout")
30
+ log.trace("Request #{request.rid} sent to #{request.address} with #{t}s timeout")
31
+
32
32
  send_message sock, request
33
33
 
34
- log.debug("Waiting for #{request.rid}")
34
+ log.trace("Waiting for #{request.rid}")
35
35
  response = receive_message(sock)
36
36
 
37
37
  end
38
38
  rescue ::Timeout::Error
39
- log.debug("Request #{request.rid} exit with timeout after #{t}s")
39
+ log.info("Request #{request.rid} exit with timeout after #{t}s")
40
40
  raise ZSS::Socket::TimeoutError, "call timeout after #{t}s"
41
41
  end
42
42
  end
@@ -62,7 +62,7 @@ module ZSS
62
62
  socket.setsockopt(ZMQ::LINGER, 0)
63
63
  socket.connect(socket_address)
64
64
 
65
- log.debug("#{socket.identity} connected to #{socket_address}")
65
+ log.trace("#{socket.identity} connected to #{socket_address}")
66
66
 
67
67
  yield socket
68
68
  ensure
@@ -71,7 +71,7 @@ module ZSS
71
71
 
72
72
  def send_message socket, message
73
73
 
74
- log.debug("Sending:\n #{message}") if log.is_debug
74
+ log.trace("Sending:\n #{message}") if log.is_debug
75
75
 
76
76
  frames = message.to_frames
77
77
 
@@ -86,7 +86,7 @@ module ZSS
86
86
  check! socket.recv_strings(frames = [])
87
87
  message = Message.parse frames
88
88
 
89
- log.debug("Receiving: \n #{message}") if log.is_debug
89
+ log.trace("Receiving: \n #{message}") if log.is_debug
90
90
 
91
91
  message
92
92
  end
@@ -1,3 +1,3 @@
1
1
  module ZSS
2
- VERSION = '0.2.5'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -33,7 +33,7 @@ describe ZSS::Service do
33
33
  run_broker_for_service(broker_backend, message) do |msg|
34
34
  expect(msg.payload).to eq("PONG")
35
35
  expect(msg.status).to eq(200)
36
- expect(msg.headers).to eq({ "took" => "0s" })
36
+ expect(msg.headers.took).to eq("0s")
37
37
  subject.stop
38
38
  EM.stop
39
39
  end
@@ -18,11 +18,3 @@ require 'zss'
18
18
  require 'timeout'
19
19
 
20
20
  Dir['spec/support/**/*.rb'].each &method(:require)
21
-
22
- RSpec.configure do |c|
23
- c.around(:each) do |example|
24
- Timeout::timeout(2) {
25
- example.run
26
- }
27
- end
28
- end
@@ -162,7 +162,7 @@ describe ZSS::Service do
162
162
 
163
163
  expect(message.type).to eq(ZSS::Message::Type::REP)
164
164
  expect(message.status).to eq(200)
165
- expect(message.headers).to eq({ "took" => "0s" })
165
+ expect(message.headers.took).to eq("0s")
166
166
 
167
167
  done
168
168
 
@@ -172,6 +172,28 @@ describe ZSS::Service do
172
172
 
173
173
  end
174
174
 
175
+ it('returns response time header') do
176
+ service = DummyService.new
177
+ subject.add_route(service, :ping)
178
+
179
+ EM.run do
180
+ allow(socket).to receive(:on) do |event, &block|
181
+ EM.add_timer { block.call *message_parts }
182
+ end
183
+
184
+ subject.run
185
+
186
+ expect(socket).to receive(:send_msg) do |*frames|
187
+ message = ZSS::Message.parse(frames)
188
+ expect(message.headers["zss-response-time"]).to be
189
+ done
190
+
191
+ true
192
+ end
193
+ end
194
+
195
+ end
196
+
175
197
  context('on error') do
176
198
 
177
199
  it('returns 404 on invalid sid') do
@@ -32,9 +32,9 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_dependency 'msgpack', '~> 0.5'
34
34
  spec.add_dependency 'ffi-rzmq', '~> 2.0'
35
- spec.add_dependency 'activesupport', '~> 4.1'
35
+ spec.add_dependency 'activesupport', '= 4.1'
36
36
  spec.add_dependency 'hashie', '~> 3.2'
37
37
  spec.add_dependency 'daemons', '~> 1.1'
38
38
  spec.add_dependency 'em-zeromq', '~> 0.5'
39
- spec.add_dependency 'logger_facade', '~> 0.1'
39
+ spec.add_dependency 'logger_facade', '~> 0.3.2'
40
40
  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.2.5
4
+ version: 0.3.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-12-22 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -140,14 +140,14 @@ dependencies:
140
140
  name: activesupport
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - '='
144
144
  - !ruby/object:Gem::Version
145
145
  version: '4.1'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - '='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '4.1'
153
153
  - !ruby/object:Gem::Dependency
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '0.1'
201
+ version: 0.3.2
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: '0.1'
208
+ version: 0.3.2
209
209
  description: ZeroMQ SOA Suite
210
210
  email:
211
211
  - prnjanuario@gmail.com