Skip to content

Commit d70733c

Browse files
(fix): fix loop on batch event processor (#224)
* fix loop * sleep for flush interval only if no items * block on the pop * hang on poll if we have gotten two nil items after sleep. * cleanup rubocop lint * add logging * sleep interval in seconds * cleanup lint errors * make sleep interval a double. * get tests passing * refactor to only sleep a portion of the max nil count. When max nil count is reached, the timer will also have been reached and it will flush. then hang on poll. * fix lint errors * take out longer sleep * fix lint * allow for flush interval to pass, if there have been no entries, flush and then hang on pop * remove sleep * added comments * add a debug log for successful event sent * fix tests to expect a log event
1 parent 3e64576 commit d70733c

File tree

4 files changed

+28
-10
lines changed

4 files changed

+28
-10
lines changed

lib/optimizely/event/batch_event_processor.rb

+20-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class BatchEventProcessor < EventProcessor
3131
DEFAULT_BATCH_INTERVAL = 30_000 # interval in milliseconds
3232
DEFAULT_QUEUE_CAPACITY = 1000
3333
DEFAULT_TIMEOUT_INTERVAL = 5 # interval in seconds
34+
MAX_NIL_COUNT = 3
3435

3536
FLUSH_SIGNAL = 'FLUSH_SIGNAL'
3637
SHUTDOWN_SIGNAL = 'SHUTDOWN_SIGNAL'
@@ -107,16 +108,32 @@ def stop!
107108
private
108109

109110
def run
111+
# if we receive a number of item nils that reach MAX_NIL_COUNT,
112+
# then we hang on the pop via setting use_pop to false
113+
@nil_count = 0
114+
# hang on pop if true
115+
@use_pop = false
110116
loop do
111-
flush_queue! if Helpers::DateTimeUtils.create_timestamp > @flushing_interval_deadline
117+
if Helpers::DateTimeUtils.create_timestamp >= @flushing_interval_deadline
118+
@logger.log(Logger::DEBUG, 'Deadline exceeded flushing current batch.')
119+
flush_queue!
120+
@flushing_interval_deadline = Helpers::DateTimeUtils.create_timestamp + @flush_interval
121+
@use_pop = true if @nil_count > MAX_NIL_COUNT
122+
end
112123

113-
item = @event_queue.pop if @event_queue.length.positive?
124+
item = @event_queue.pop if @event_queue.length.positive? || @use_pop
114125

115126
if item.nil?
116-
sleep(0.05)
127+
# when nil count is greater than MAX_NIL_COUNT, we hang on the pop until there is an item available.
128+
# this avoids to much spinning of the loop.
129+
@nil_count += 1
117130
next
118131
end
119132

133+
# reset nil_count and use_pop if we have received an item.
134+
@nil_count = 0
135+
@use_pop = false
136+
120137
if item == SHUTDOWN_SIGNAL
121138
@logger.log(Logger::DEBUG, 'Received shutdown signal.')
122139
break

lib/optimizely/event_dispatcher.rb

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def dispatch_event(event)
5959
when 500...600
6060
@logger.log(Logger::ERROR, error_msg)
6161
@error_handler.handle_error(HTTPCallError.new("HTTP Server Error: #{response.code}"))
62+
else
63+
@logger.log(Logger::DEBUG, 'event successfully sent with response code ' + response.code.to_s)
6264
end
6365
rescue Timeout::Error => e
6466
@logger.log(Logger::ERROR, "Request Timed out. Error: #{e}")

spec/event/batch_event_processor_spec.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
@event_processor.process(conversion_event)
6464
# flush interval is set to 100ms. Wait for 300ms and assert that event is dispatched.
65-
sleep 0.3
65+
sleep 1
6666

6767
expect(@event_dispatcher).to have_received(:dispatch_event).with(log_event).once
6868
expect(@notification_center).to have_received(:send_notifications).with(
@@ -153,7 +153,6 @@
153153

154154
expect(@event_dispatcher).to have_received(:dispatch_event).with(log_event).once
155155
expect(spy_logger).to have_received(:log).with(Logger::DEBUG, 'Revisions mismatched: Flushing current batch.').once
156-
expect(spy_logger).not_to have_received(:log).with(Logger::DEBUG, 'Deadline exceeded flushing current batch.')
157156
end
158157

159158
it 'should flush on mismatch project id' do

spec/event_dispatcher_spec.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@
146146

147147
response = @customized_event_dispatcher.dispatch_event(event)
148148

149-
expect(response).to be_nil
150-
expect(spy_logger).not_to have_received(:log)
151-
expect(error_handler).not_to have_received(:handle_error)
149+
expect(response).to have_received(:log)
150+
expect(spy_logger).to have_received(:log)
151+
expect(error_handler).to_not have_received(:handle_error)
152152
end
153153

154154
it 'should do nothing on response with status code 600' do
@@ -157,8 +157,8 @@
157157

158158
response = @customized_event_dispatcher.dispatch_event(event)
159159

160-
expect(response).to be_nil
161-
expect(spy_logger).not_to have_received(:log)
160+
expect(response).to have_received(:log)
161+
expect(spy_logger).to have_received(:log)
162162
expect(error_handler).not_to have_received(:handle_error)
163163
end
164164
end

0 commit comments

Comments
 (0)