zss 0.2.5 → 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: 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