@@ -58,6 +58,9 @@ def initialize(tag_prefix = nil, *args)
58
58
@port = options [ :port ]
59
59
@socket_path = options [ :socket_path ]
60
60
61
+ @require_ack_response = options [ :require_ack_response ]
62
+ @ack_response_timeout = options [ :ack_response_timeout ] || 190
63
+
61
64
@mon = Monitor . new
62
65
@pending = nil
63
66
@connect_error_history = [ ]
@@ -108,7 +111,7 @@ def close
108
111
if @pending
109
112
begin
110
113
@pending . each do |tag , record |
111
- send_data ( [ tag , record ] . to_msgpack )
114
+ send_data ( tag , record )
112
115
end
113
116
rescue => e
114
117
set_last_error ( e )
@@ -184,7 +187,7 @@ def write(tag, time, map)
184
187
185
188
begin
186
189
@pending . each do |tag , record |
187
- send_data ( [ tag , record ] . to_msgpack )
190
+ send_data ( tag , record )
188
191
end
189
192
@pending = nil
190
193
true
@@ -202,11 +205,17 @@ def write(tag, time, map)
202
205
}
203
206
end
204
207
205
- def send_data ( data )
208
+ def send_data ( tag , record )
206
209
unless connect?
207
210
connect!
208
211
end
209
- @con . write data
212
+ if @require_ack_response
213
+ option = { }
214
+ option [ 'chunk' ] = generate_chunk
215
+ @con . write [ tag , record , option ] . to_msgpack
216
+ else
217
+ @con . write [ tag , record ] . to_msgpack
218
+ end
210
219
#while true
211
220
# puts "sending #{data.length} bytes"
212
221
# if data.length > 32*1024
@@ -221,6 +230,21 @@ def send_data(data)
221
230
# data = data[n..-1]
222
231
#end
223
232
233
+ if @require_ack_response && @ack_response_timeout > 0
234
+ if IO . select ( [ @con ] , nil , nil , @ack_response_timeout )
235
+ raw_data = @con . recv ( 1024 )
236
+
237
+ if raw_data . empty?
238
+ raise "Closed connection"
239
+ else
240
+ response = MessagePack . unpack ( raw_data )
241
+ if response [ 'ack' ] != option [ 'chunk' ]
242
+ raise "ack in response and chunk id in sent data are different"
243
+ end
244
+ end
245
+ end
246
+ end
247
+
224
248
true
225
249
end
226
250
@@ -259,6 +283,10 @@ def set_last_error(e)
259
283
# TODO: Check non GVL env
260
284
@last_error [ Thread . current . object_id ] = e
261
285
end
286
+
287
+ def generate_chunk
288
+ Base64 . encode64 ( ( [ SecureRandom . random_number ( 1 << 32 ) ] * 4 ) . pack ( 'NNNN' ) ) . chomp
289
+ end
262
290
end
263
291
end
264
292
end
0 commit comments