20
20
module Optimizely
21
21
class BatchEventProcessor < EventProcessor
22
22
# BatchEventProcessor is a batched implementation of the Interface EventProcessor.
23
- # Events passed to the BatchEventProcessor are immediately added to a EventQueue.
23
+ # Events passed to the BatchEventProcessor are immediately added to an EventQueue.
24
24
# The BatchEventProcessor maintains a single consumer thread that pulls events off of
25
25
# the BlockingQueue and buffers them for either a configured batch size or for a
26
26
# maximum duration before the resulting LogEvent is sent to the NotificationCenter.
@@ -30,6 +30,7 @@ class BatchEventProcessor < EventProcessor
30
30
DEFAULT_BATCH_SIZE = 10
31
31
DEFAULT_BATCH_INTERVAL = 30_000 # interval in milliseconds
32
32
DEFAULT_QUEUE_CAPACITY = 1000
33
+ DEFAULT_TIMEOUT_INTERVAL = 5 # interval in seconds
33
34
34
35
FLUSH_SIGNAL = 'FLUSH_SIGNAL'
35
36
SHUTDOWN_SIGNAL = 'SHUTDOWN_SIGNAL'
@@ -58,8 +59,6 @@ def initialize(
58
59
DEFAULT_BATCH_INTERVAL
59
60
end
60
61
@notification_center = notification_center
61
- @mutex = Mutex . new
62
- @received = ConditionVariable . new
63
62
@current_batch = [ ]
64
63
@started = false
65
64
start!
@@ -71,15 +70,13 @@ def start!
71
70
return
72
71
end
73
72
@flushing_interval_deadline = Helpers ::DateTimeUtils . create_timestamp + @flush_interval
73
+ @logger . log ( Logger ::INFO , 'Starting scheduler.' )
74
74
@thread = Thread . new { run }
75
75
@started = true
76
76
end
77
77
78
78
def flush
79
- @mutex . synchronize do
80
- @event_queue << FLUSH_SIGNAL
81
- @received . signal
82
- end
79
+ @event_queue << FLUSH_SIGNAL
83
80
end
84
81
85
82
def process ( user_event )
@@ -90,56 +87,38 @@ def process(user_event)
90
87
return
91
88
end
92
89
93
- @mutex . synchronize do
94
- begin
95
- @event_queue << user_event
96
- @received . signal
97
- rescue Exception
98
- @logger . log ( Logger ::WARN , 'Payload not accepted by the queue.' )
99
- return
100
- end
90
+ begin
91
+ @event_queue . push ( user_event , true )
92
+ rescue Exception
93
+ @logger . log ( Logger ::WARN , 'Payload not accepted by the queue.' )
94
+ return
101
95
end
102
96
end
103
97
104
98
def stop!
105
99
return unless @started
106
100
107
- @mutex . synchronize do
108
- @event_queue << SHUTDOWN_SIGNAL
109
- @received . signal
110
- end
111
-
101
+ @logger . log ( Logger ::INFO , 'Stopping scheduler.' )
102
+ @event_queue << SHUTDOWN_SIGNAL
103
+ @thread . join ( DEFAULT_TIMEOUT_INTERVAL )
112
104
@started = false
113
- @logger . log ( Logger ::WARN , 'Stopping scheduler.' )
114
- @thread . exit
115
105
end
116
106
117
107
private
118
108
119
109
def run
120
110
loop do
121
- if Helpers ::DateTimeUtils . create_timestamp > @flushing_interval_deadline
122
- @logger . log (
123
- Logger ::DEBUG ,
124
- 'Deadline exceeded flushing current batch.'
125
- )
126
- flush_queue!
127
- end
128
-
129
- item = nil
111
+ flush_queue! if Helpers ::DateTimeUtils . create_timestamp > @flushing_interval_deadline
130
112
131
- @mutex . synchronize do
132
- @received . wait ( @mutex , 0.05 )
133
- item = @event_queue . pop if @event_queue . length . positive?
134
- end
113
+ item = @event_queue . pop if @event_queue . length . positive?
135
114
136
115
if item . nil?
137
116
sleep ( 0.05 )
138
117
next
139
118
end
140
119
141
120
if item == SHUTDOWN_SIGNAL
142
- @logger . log ( Logger ::INFO , 'Received shutdown signal.' )
121
+ @logger . log ( Logger ::DEBUG , 'Received shutdown signal.' )
143
122
break
144
123
end
145
124
@@ -152,7 +131,7 @@ def run
152
131
add_to_batch ( item ) if item . is_a? Optimizely ::UserEvent
153
132
end
154
133
rescue SignalException
155
- @logger . log ( Logger ::INFO , 'Interrupted while processing buffer.' )
134
+ @logger . log ( Logger ::ERROR , 'Interrupted while processing buffer.' )
156
135
rescue Exception => e
157
136
@logger . log ( Logger ::ERROR , "Uncaught exception processing buffer. #{ e . message } " )
158
137
ensure
@@ -168,6 +147,11 @@ def flush_queue!
168
147
169
148
log_event = Optimizely ::EventFactory . create_log_event ( @current_batch , @logger )
170
149
begin
150
+ @logger . log (
151
+ Logger ::INFO ,
152
+ 'Flushing Queue.'
153
+ )
154
+
171
155
@event_dispatcher . dispatch_event ( log_event )
172
156
@notification_center &.send_notifications (
173
157
NotificationCenter ::NOTIFICATION_TYPES [ :LOG_EVENT ] ,
@@ -192,7 +176,7 @@ def add_to_batch(user_event)
192
176
@current_batch << user_event
193
177
return unless @current_batch . length >= @batch_size
194
178
195
- @logger . log ( Logger ::DEBUG , 'Flushing on max batch size! ' )
179
+ @logger . log ( Logger ::DEBUG , 'Flushing on max batch size. ' )
196
180
flush_queue!
197
181
end
198
182
0 commit comments