Skip to content

Commit 3baf024

Browse files
committed
Merge branch 'mnoman/AddBatchEP' into mnoman/log_event_notification
# Conflicts: # optimizely/event/event_processor.py
2 parents 3b2cb4a + 01a8ea1 commit 3baf024

File tree

4 files changed

+22
-21
lines changed

4 files changed

+22
-21
lines changed

optimizely/event/event_factory.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
from optimizely.helpers import enums
1515
from optimizely.helpers import event_tag_utils
1616
from optimizely.helpers import validator
17-
from . import user_event
18-
from . import payload
1917
from . import log_event
18+
from . import payload
19+
from . import user_event
2020

2121
CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom'
2222

optimizely/event/event_processor.py

+17-15
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
from optimizely.event_dispatcher import EventDispatcher as default_event_dispatcher
2323
from optimizely.helpers import enums
2424
from optimizely.helpers import validator
25-
from .user_event import UserEvent
2625
from .event_factory import EventFactory
26+
from .user_event import UserEvent
2727

2828
ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})
2929

@@ -33,12 +33,16 @@ class BaseEventProcessor(ABC):
3333

3434
@abc.abstractmethod
3535
def process(user_event):
36+
""" Method to provide intermediary processing stage within event production.
37+
Args:
38+
user_event: UserEvent instance that needs to be processed and dispatched.
39+
"""
3640
pass
3741

3842

3943
class BatchEventProcessor(BaseEventProcessor):
4044
"""
41-
BatchEventProcessor is a batched implementation of the BaseEventProcessor.
45+
BatchEventProcessor is an implementation of the BaseEventProcessor that batches events.
4246
The BatchEventProcessor maintains a single consumer thread that pulls events off of
4347
the blocking queue and buffers them for either a configured batch size or for a
4448
maximum duration before the resulting LogEvent is sent to the EventDispatcher.
@@ -89,17 +93,15 @@ def __init__(self,
8993
if self._validate_intantiation_props(timeout_interval, 'timeout_interval') \
9094
else self._DEFAULT_TIMEOUT_INTERVAL
9195
self.notification_center = notification_center
92-
93-
self._is_started = False
9496
self._current_batch = list()
9597

9698
if start_on_init is True:
9799
self.start()
98100

99101
@property
100-
def is_started(self):
102+
def is_running(self):
101103
""" Property to check if consumer thread is alive or not. """
102-
return self._is_started
104+
return self.executor.isAlive()
103105

104106
def _validate_intantiation_props(self, prop, prop_name):
105107
""" Method to determine if instantiation properties like batch_size, flush_interval
@@ -137,17 +139,15 @@ def _get_time(self, _time=None):
137139

138140
def start(self):
139141
""" Starts the batch processing thread to batch events. """
140-
if self.is_started:
141-
self.logger.warning('Service already started')
142+
if hasattr(self, 'executor') and self.is_running:
143+
self.logger.warning('BatchEventProcessor already started.')
142144
return
143145

144146
self.flushing_interval_deadline = self._get_time() + self._get_time(self.flush_interval.total_seconds())
145147
self.executor = threading.Thread(target=self._run)
146148
self.executor.setDaemon(True)
147149
self.executor.start()
148150

149-
self._is_started = True
150-
151151
def _run(self):
152152
""" Triggered as part of the thread which batches events or flushes event_queue and sleeps
153153
periodically if queue is empty.
@@ -212,6 +212,10 @@ def _flush_queue(self):
212212
self.logger.error('Error dispatching event: ' + str(log_event) + ' ' + str(e))
213213

214214
def process(self, user_event):
215+
""" Method to process the user_event by putting it in event_queue.
216+
Args:
217+
user_event: UserEvent Instance.
218+
"""
215219
if not isinstance(user_event, UserEvent):
216220
self.logger.error('Provided event is in an invalid format.')
217221
return
@@ -255,12 +259,10 @@ def _should_split(self, user_event):
255259

256260
def stop(self):
257261
""" Stops and disposes batch event processor. """
258-
259262
self.event_queue.put(self._SHUTDOWN_SIGNAL)
263+
self.logger.warning('Stopping Scheduler.')
264+
260265
self.executor.join(self.timeout_interval.total_seconds())
261266

262-
if self.executor.isAlive():
267+
if self.is_running:
263268
self.logger.error('Timeout exceeded while attempting to close for ' + str(self.timeout_interval) + ' ms.')
264-
265-
self.logger.warning('Stopping Scheduler.')
266-
self._is_started = False

tests/test_config_manager.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ def test_fetch_datafile(self, _):
278278

279279
def test_is_running(self, _):
280280
""" Test that polling thread is running after instance of PollingConfigManager is created. """
281-
with mock.patch('optimizely.config_manager.PollingConfigManager.fetch_datafile') as mock_fetch_datafile:
281+
with mock.patch('optimizely.config_manager.PollingConfigManager.fetch_datafile'):
282282
project_config_manager = config_manager.PollingConfigManager(sdk_key='some_key')
283283
self.assertTrue(project_config_manager.is_running)
284-
mock_fetch_datafile.assert_called_with()

tests/test_event_processor.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,10 @@ def test_stop_and_start(self):
267267
event_dispatcher.expect_conversion(self.event_name, self.test_user_id)
268268

269269
self._event_processor.start()
270-
self.assertStrictTrue(self._event_processor.is_started)
270+
self.assertStrictTrue(self._event_processor.is_running)
271271

272272
self._event_processor.stop()
273-
self.assertStrictFalse(self._event_processor.is_started)
273+
self.assertStrictFalse(self._event_processor.is_running)
274274

275275
self.assertEqual(0, self._event_processor.event_queue.qsize())
276276

0 commit comments

Comments
 (0)