log-courier 1.0.21.ga82ca4c → 1.1

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: 480d6e6a5958b6f307727dfa1713e8a9c0a10d29
4
- data.tar.gz: 2f2de7aeedd2e539a16412dd40f8321ecc9cff20
3
+ metadata.gz: 68e7cf906de75f2ac3838d007c24380f0e8a3740
4
+ data.tar.gz: dadf3d48bb4302f35be2255e1d168bb1699cde04
5
5
  SHA512:
6
- metadata.gz: 3d2d449239c58e05a7654ad0f77148b2fd8ac5ebf0094f50b85c7311cb904650cc426a55aa2918a9b9334c70c283ca1d7aa47cb47c94b0999011bfc0949270b7
7
- data.tar.gz: 8e51f6507f0b12a7ed56a17fb28213ea9a7f71b5257544c8191ad19bb70e91f1c6a8e940d37203fab587f3c564deb0551426fc8996081a7101faaf707d014748
6
+ metadata.gz: 5eae260c97dc6d05ffca1c7160aaeb153289020e289335948a5ca3fc96019c2b418a8fe6d5846ad53ca7b7f9a569d3679acc870f40743f14f86618ac97ac6c9e
7
+ data.tar.gz: 16fe209e290aedb5fefc707733d5860889dbb3a11ff4900b1c04543729bf184072142250ab9bdca398f1363052ce11c5d94645a00ca4ec108338b74cb106dd94
@@ -22,10 +22,11 @@ require 'multi_json'
22
22
  require 'thread'
23
23
  require 'zlib'
24
24
 
25
+ class NativeException; end
26
+
25
27
  module LogCourier
26
- # TODO: Make these shared
27
- class ClientShutdownSignal < StandardError; end
28
- class ClientProtocolError < StandardError; end
28
+ class ShutdownSignal < StandardError; end
29
+ class ProtocolError < StandardError; end
29
30
 
30
31
  # Describes a pending payload
31
32
  class PendingPayload
@@ -93,8 +94,8 @@ module LogCourier
93
94
 
94
95
  def shutdown
95
96
  # Raise a shutdown signal in the spooler and wait for it
96
- @spooler_thread.raise ClientShutdownSignal
97
- @io_thread.raise ClientShutdownSignal
97
+ @spooler_thread.raise ShutdownSignal
98
+ @io_thread.raise ShutdownSignal
98
99
  @spooler_thread.join
99
100
  @io_thread.join
100
101
  end
@@ -123,7 +124,7 @@ module LogCourier
123
124
  @io_control << ['E', spooled]
124
125
  end
125
126
  end
126
- rescue ClientShutdownSignal
127
+ rescue ShutdownSignal
127
128
  # Just shutdown
128
129
  0
129
130
  end
@@ -224,13 +225,13 @@ module LogCourier
224
225
  # Reset keepalive timeout
225
226
  reset_keepalive
226
227
  end
227
- rescue ClientProtocolError => e
228
+ rescue ProtocolError => e
228
229
  # Reconnect required due to a protocol error
229
230
  @logger.warn("[LogCourierClient] Protocol error: #{e}") unless @logger.nil?
230
231
  rescue TimeoutError
231
232
  # Reconnect due to timeout
232
233
  @logger.warn('[LogCourierClient] Timeout occurred') unless @logger.nil?
233
- rescue ClientShutdownSignal
234
+ rescue ShutdownSignal
234
235
  # Shutdown, break out
235
236
  break
236
237
  rescue => e
@@ -311,7 +312,7 @@ module LogCourier
311
312
  def process_pong(message)
312
313
  # Sanity
313
314
  if message.length != 0
314
- raise ClientProtocolError, "Unexpected data attached to pong message (#{message.length})"
315
+ raise ProtocolError, "Unexpected data attached to pong message (#{message.length})"
315
316
  end
316
317
 
317
318
  # No longer pending a PONG
@@ -321,7 +322,7 @@ module LogCourier
321
322
  def process_ackn(message)
322
323
  # Sanity
323
324
  if message.length != 20
324
- raise ClientProtocolError, "ACKN message size invalid (#{message.length})"
325
+ raise ProtocolError, "ACKN message size invalid (#{message.length})"
325
326
  end
326
327
 
327
328
  # Grab nonce
@@ -54,7 +54,7 @@ module LogCourier
54
54
  def connect(io_control)
55
55
  begin
56
56
  tls_connect
57
- rescue ClientShutdownSignal
57
+ rescue ShutdownSignal
58
58
  raise
59
59
  rescue
60
60
  # TODO: Make this configurable
@@ -74,9 +74,9 @@ module LogCourier
74
74
  end
75
75
 
76
76
  def disconnect
77
- @send_thread.raise ClientShutdownSignal
77
+ @send_thread.raise ShutdownSignal
78
78
  @send_thread.join
79
- @recv_thread.raise ClientShutdownSignal
79
+ @recv_thread.raise ShutdownSignal
80
80
  @recv_thread.join
81
81
  end
82
82
 
@@ -111,7 +111,7 @@ module LogCourier
111
111
  rescue OpenSSL::SSL::SSLError, IOError, Errno::ECONNRESET => e
112
112
  @logger.warn("[LogCourierClient] SSL write error: #{e}") unless @logger.nil?
113
113
  io_control << ['F']
114
- rescue ClientShutdownSignal
114
+ rescue ShutdownSignal
115
115
  # Just shutdown
116
116
  rescue => e
117
117
  @logger.warn("[LogCourierClient] Unknown SSL write error: #{e}") unless @logger.nil?
@@ -147,7 +147,7 @@ module LogCourier
147
147
  rescue EOFError
148
148
  @logger.warn("[LogCourierClient] Connection closed by server") unless @logger.nil?
149
149
  io_control << ['F']
150
- rescue ClientShutdownSignal
150
+ rescue ShutdownSignal
151
151
  # Just shutdown
152
152
  rescue => e
153
153
  @logger.warn("[LogCourierClient] Unknown SSL read error: #{e}") unless @logger.nil?
@@ -206,12 +206,13 @@ module LogCourier
206
206
  socket
207
207
  rescue OpenSSL::SSL::SSLError, IOError, Errno::ECONNRESET => e
208
208
  @logger.warn("[LogCourierClient] Connection to #{@options[:addresses][0]}:#{@options[:port]} failed: #{e}") unless @logger.nil?
209
- rescue ClientShutdownSignal
209
+ rescue ShutdownSignal
210
210
  # Just shutdown
211
211
  0
212
- rescue => e
212
+ rescue StandardError, NativeException => e
213
213
  @logger.warn("[LogCourierClient] Unknown connection failure to #{@options[:addresses][0]}:#{@options[:port]}: #{e}") unless @logger.nil?
214
214
  @logger.warn("[LogCourierClient] #{e.backtrace}: #{e.message} (#{e.class})") unless @logger.nil?
215
+ raise e
215
216
  end
216
217
  end
217
218
  end
@@ -22,6 +22,8 @@ require 'multi_json'
22
22
  require 'thread'
23
23
  require 'zlib'
24
24
 
25
+ class NativeException; end
26
+
25
27
  module LogCourier
26
28
  class TimeoutError < StandardError; end
27
29
  class ShutdownSignal < StandardError; end
@@ -158,7 +160,7 @@ module LogCourier
158
160
  # Decode the JSON
159
161
  begin
160
162
  event = @json_adapter.load(data_buf, @json_options)
161
- rescue MultiJson::ParserError => e
163
+ rescue MultiJson::ParseError => e
162
164
  @logger.warn("[LogCourierServer] JSON parse failure, falling back to plain-text: #{e}") unless @logger.nil?
163
165
  event = { 'message' => data_buf }
164
166
  end
@@ -169,6 +171,7 @@ module LogCourier
169
171
  rescue TimeoutError
170
172
  # Full pipeline, partial ack
171
173
  # NOTE: comm.send can raise a Timeout::Error of its own
174
+ @logger.debug "[LogCourierServer] Partially acknowledging message #{nonce.hash} sequence #{sequence}" unless @logger.nil?
172
175
  comm.send 'ACKN', [nonce, sequence].pack('A*N')
173
176
  ack_timeout = Time.now.to_i + 5
174
177
  retry
@@ -179,6 +182,7 @@ module LogCourier
179
182
 
180
183
  # Acknowledge the full message
181
184
  # NOTE: comm.send can raise a Timeout::Error
185
+ @logger.debug "[LogCourierServer] Acknowledging message #{nonce.hash} sequence #{sequence}" unless @logger.nil?
182
186
  comm.send 'ACKN', [nonce, sequence].pack('A*N')
183
187
  end
184
188
  end
@@ -100,7 +100,7 @@ module LogCourier
100
100
  end
101
101
 
102
102
  if @options[:port] == 0
103
- @logger.warn '[LogCourierServer] Transport ' + @options[:transport] + ' is listening on ephemeral port ' + @port.to_s
103
+ @logger.warn '[LogCourierServer] Transport ' + @options[:transport] + ' is listening on ephemeral port ' + @port.to_s unless @logger.nil?
104
104
  end
105
105
  rescue => e
106
106
  raise "[LogCourierServer] Failed to initialise: #{e}"
@@ -139,6 +139,11 @@ module LogCourier
139
139
  rescue ShutdownSignal
140
140
  # Capture shutting down signal
141
141
  0
142
+ rescue StandardError, NativeException => e
143
+ # Some other unknown problem
144
+ @logger.warn("[LogCourierServer] Unknown error: #{e}") unless @logger.nil?
145
+ @logger.warn("[LogCourierServer] #{e.backtrace}: #{e.message} (#{e.class})") unless @logger.nil?
146
+ raise e
142
147
  ensure
143
148
  # Raise shutdown in all client threads and join then
144
149
  client_threads.each do |_, thr|
@@ -79,18 +79,20 @@ module LogCourier
79
79
  @poller = ZMQ::Poller.new
80
80
 
81
81
  if @options[:port] == 0
82
- @logger.warn '[LogCourierServer] Transport ' + @options[:transport] + ' is listening on ephemeral port ' + @port.to_s
82
+ @logger.warn '[LogCourierServer] Transport ' + @options[:transport] + ' is listening on ephemeral port ' + @port.to_s unless @logger.nil?
83
83
  end
84
84
  rescue => e
85
85
  raise "[LogCourierServer] Failed to initialise: #{e}"
86
86
  end
87
87
 
88
- @logger.info "[LogCourierServer] libzmq version #{libversion}"
89
- @logger.info "[LogCourierServer] ffi-rzmq-core version #{LibZMQ::VERSION}"
90
- @logger.info "[LogCourierServer] ffi-rzmq version #{ZMQ.version}"
88
+ @logger.info "[LogCourierServer] libzmq version #{libversion}" unless @logger.nil?
89
+ @logger.info "[LogCourierServer] ffi-rzmq-core version #{LibZMQ::VERSION}" unless @logger.nil?
90
+ @logger.info "[LogCourierServer] ffi-rzmq version #{ZMQ.version}" unless @logger.nil?
91
91
 
92
92
  # TODO: Implement workers option by receiving on a ROUTER and proxying to a DEALER, with workers connecting to the DEALER
93
93
 
94
+ @return_route = []
95
+
94
96
  reset_timeout
95
97
  end
96
98
 
@@ -108,6 +110,7 @@ module LogCourier
108
110
  begin
109
111
  begin
110
112
  # Try to receive a message
113
+ reset_timeout
111
114
  data = []
112
115
  rc = @socket.recv_strings(data, ZMQ::DONTWAIT)
113
116
  unless ZMQ::Util.resultcode_ok?(rc)
@@ -117,7 +120,8 @@ module LogCourier
117
120
  @poller.deregister @socket, ZMQ::POLLIN | ZMQ::POLLOUT
118
121
  @poller.register @socket, ZMQ::POLLIN
119
122
  while @poller.poll(1_000) == 0
120
- raise TimeoutError if Time.now.to_i >= @timeout
123
+ # Using this inner while triggers pollThreadEvents in JRuby which checks for Thread.raise immediately
124
+ raise TimeoutError while Time.now.to_i >= @timeout
121
125
  end
122
126
  next
123
127
  end
@@ -126,21 +130,31 @@ module LogCourier
126
130
  next
127
131
  end
128
132
 
129
- # Pre-send the routing information and remove it from data
130
- data.delete_if do |msg|
131
- reset_timeout
132
- send_with_poll msg, true
133
- if ZMQ::Util.errno != ZMQ::EAGAIN
134
- @logger.warn "[LogCourierServer] Message send failed: #{ZMQ::Util.error_string}" unless @logger.nil?
135
- raise TimeoutError
136
- end
137
- break if msg == ""
138
- true
133
+ # Save the routing information that appears before the null messages
134
+ @return_route = []
135
+ @return_route.push data.shift until data.length == 0 || data[0] == ''
136
+
137
+ if data.length == 0
138
+ @logger.warn '[LogCourierServer] Invalid message: no data' unless @logger.nil?
139
+ next
140
+ elsif data.length == 1
141
+ @logger.warn '[LogCourierServer] Invalid message: empty data' unless @logger.nil?
142
+ next
139
143
  end
144
+
145
+ # Drop the null message separator
140
146
  data.shift
141
147
 
142
148
  if data.length != 1
143
- @logger.warn '[LogCourierServer] Invalid message: multipart unexpected' unless @logger.nil?
149
+ @logger.warn "[LogCourierServer] Invalid message: multipart unexpected (#{data.length})" unless @logger.nil?
150
+ if !@logger.nil? && @logger.debug?
151
+ i = 0
152
+ data.each do |msg|
153
+ i += 1
154
+ part = msg[0..31].gsub(/[^[:print:]]/, '.')
155
+ @logger.debug "[LogCourierServer] Part #{i}: #{part.length}:[#{part}]"
156
+ end
157
+ end
144
158
  else
145
159
  recv(data.first, &block)
146
160
  end
@@ -155,10 +169,11 @@ module LogCourier
155
169
  rescue ShutdownSignal
156
170
  # Shutting down
157
171
  @logger.warn('[LogCourierServer] Server shutting down') unless @logger.nil?
158
- rescue => e
172
+ rescue StandardError, NativeException => e
159
173
  # Some other unknown problem
160
174
  @logger.warn("[LogCourierServer] Unknown error: #{e}") unless @logger.nil?
161
175
  @logger.warn("[LogCourierServer] #{e.backtrace}: #{e.message} (#{e.class})") unless @logger.nil?
176
+ raise e
162
177
  ensure
163
178
  @socket.close
164
179
  @context.terminate
@@ -187,8 +202,14 @@ module LogCourier
187
202
  end
188
203
 
189
204
  def send(signature, message)
190
- reset_timeout
191
205
  data = signature + [message.length].pack('N') + message
206
+
207
+ # Send the return route and then the message
208
+ reset_timeout
209
+ @return_route.each do |msg|
210
+ send_with_poll msg, true
211
+ end
212
+ send_with_poll '', true
192
213
  send_with_poll data
193
214
  end
194
215
 
@@ -206,12 +227,13 @@ module LogCourier
206
227
  @poller.deregister @socket, ZMQ::POLLIN | ZMQ::POLLOUT
207
228
  @poller.register @socket, ZMQ::POLLOUT
208
229
  while @poller.poll(1_000) == 0
209
- raise TimeoutError if Time.now.to_i >= @timeout
230
+ # Using this inner while triggers pollThreadEvents in JRuby which checks for Thread.raise immediately
231
+ raise TimeoutError while Time.now.to_i >= @timeout
210
232
  end
211
233
  end
212
234
  end
213
235
 
214
- def reset_timeout()
236
+ def reset_timeout
215
237
  # TODO: Make configurable?
216
238
  @timeout = Time.now.to_i + 1_800
217
239
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log-courier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.21.ga82ca4c
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Woods
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-29 00:00:00.000000000 Z
11
+ date: 2014-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi-rzmq
@@ -66,9 +66,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
66
  version: '0'
67
67
  required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - '>'
69
+ - - '>='
70
70
  - !ruby/object:Gem::Version
71
- version: 1.3.1
71
+ version: '0'
72
72
  requirements: []
73
73
  rubyforge_project: nowarning
74
74
  rubygems_version: 2.4.2