@@ -90,6 +90,9 @@ def initialize(tag_prefix = nil, *args)
90
90
end
91
91
@packer = @factory . packer
92
92
93
+ @require_ack_response = options [ :require_ack_response ]
94
+ @ack_response_timeout = options [ :ack_response_timeout ] || 190
95
+
93
96
@mon = Monitor . new
94
97
@pending = nil
95
98
@connect_error_history = [ ]
@@ -144,7 +147,7 @@ def close
144
147
if @pending
145
148
begin
146
149
@pending . each do |tag , record |
147
- send_data ( [ tag , record ] . to_msgpack )
150
+ send_data ( tag , record )
148
151
end
149
152
rescue => e
150
153
set_last_error ( e )
@@ -232,7 +235,7 @@ def write(tag, time, map)
232
235
233
236
begin
234
237
@pending . each do |tag , record |
235
- send_data ( [ tag , record ] . to_msgpack )
238
+ send_data ( tag , record )
236
239
end
237
240
@pending = nil
238
241
true
@@ -250,11 +253,17 @@ def write(tag, time, map)
250
253
}
251
254
end
252
255
253
- def send_data ( data )
256
+ def send_data ( tag , record )
254
257
unless connect?
255
258
connect!
256
259
end
257
- @con . write data
260
+ if @require_ack_response
261
+ option = { }
262
+ option [ 'chunk' ] = generate_chunk
263
+ @con . write [ tag , record , option ] . to_msgpack
264
+ else
265
+ @con . write [ tag , record ] . to_msgpack
266
+ end
258
267
#while true
259
268
# puts "sending #{data.length} bytes"
260
269
# if data.length > 32*1024
@@ -269,6 +278,21 @@ def send_data(data)
269
278
# data = data[n..-1]
270
279
#end
271
280
281
+ if @require_ack_response && @ack_response_timeout > 0
282
+ if IO . select ( [ @con ] , nil , nil , @ack_response_timeout )
283
+ raw_data = @con . recv ( 1024 )
284
+
285
+ if raw_data . empty?
286
+ raise "Closed connection"
287
+ else
288
+ response = MessagePack . unpack ( raw_data )
289
+ if response [ 'ack' ] != option [ 'chunk' ]
290
+ raise "ack in response and chunk id in sent data are different"
291
+ end
292
+ end
293
+ end
294
+ end
295
+
272
296
true
273
297
end
274
298
@@ -307,6 +331,10 @@ def set_last_error(e)
307
331
# TODO: Check non GVL env
308
332
@last_error [ Thread . current . object_id ] = e
309
333
end
334
+
335
+ def generate_chunk
336
+ Base64 . encode64 ( ( [ SecureRandom . random_number ( 1 << 32 ) ] * 4 ) . pack ( 'NNNN' ) ) . chomp
337
+ end
310
338
end
311
339
end
312
340
end
0 commit comments