Skip to content

Commit 060d181

Browse files
RUBY-316: Fix timer-future leak in Ruby driver
* Clean-up and refactor based on review comments.
1 parent b8598ef commit 060d181

File tree

1 file changed

+19
-30
lines changed

1 file changed

+19
-30
lines changed

lib/cassandra/protocol/cql_protocol_handler.rb

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -287,54 +287,43 @@ def maybe_start_timer
287287
# thread, it'll create a timer on a promise that no one is going to action on going forward.
288288
# So, that leads to leaking the timer until it times out. To avoid this, we want to
289289
# check that the future of the promise isn't completed before starting the timer.
290-
# Finally, we cancel a potentially existing timer before scheduling a new one. That's
291-
# just defensive programming -- that scenario shouldn't be possible right now.
292-
if @timeout
293-
@lock.lock
294-
begin
295-
@scheduler.cancel_timer(@timer) if @timer
296-
unless @future.completed?
290+
291+
return if @timeout.nil?
292+
return if @future.completed?
293+
294+
if @timer.nil?
295+
@lock.synchronize do
296+
if @timer.nil?
297+
return if @future.completed?
297298
@timer = @scheduler.schedule_timer(@timeout)
298-
@timer.on_value do
299-
time_out!
300-
end
299+
@timer.on_value { time_out! }
301300
end
302-
ensure
303-
@lock.unlock
304301
end
305302
end
306303
end
307304

308305
def fulfill(response)
309306
super
310-
311-
if @timeout
312-
@lock.lock
313-
begin
314-
if @timer
315-
@scheduler.cancel_timer(@timer)
316-
@timer = nil
317-
end
318-
ensure
319-
@lock.unlock
320-
end
321-
end
307+
maybe_cancel_timer
322308
end
323309

324310
def fail(cause)
325311
super
312+
maybe_cancel_timer
313+
end
326314

327-
if @timeout
328-
@lock.lock
329-
begin
315+
def maybe_cancel_timer
316+
return if @timeout.nil?
317+
timer = nil
318+
if @timer
319+
@lock.synchronize do
330320
if @timer
331-
@scheduler.cancel_timer(@timer)
321+
timer = @timer
332322
@timer = nil
333323
end
334-
ensure
335-
@lock.unlock
336324
end
337325
end
326+
@scheduler.cancel_timer(timer) if timer
338327
end
339328
end
340329

0 commit comments

Comments
 (0)