18
18
from datetime import timedelta
19
19
from six .moves import queue
20
20
21
- from .user_event import UserEvent
22
- from .event_factory import EventFactory
23
21
from optimizely import logger as _logging
24
22
from optimizely .event_dispatcher import EventDispatcher as default_event_dispatcher
25
23
from optimizely .helpers import enums
26
24
from optimizely .helpers import validator
25
+ from .user_event import UserEvent
26
+ from .event_factory import EventFactory
27
27
28
28
ABC = abc .ABCMeta ('ABC' , (object ,), {'__slots__' : ()})
29
29
30
30
31
- class EventProcessor (ABC ):
32
- """ Class encapsulating event_processor functionality. Override with your own processor
33
- providing process method. """
31
+ class BaseEventProcessor (ABC ):
32
+ """ Class encapsulating event processing. Override with your own implementation. """
34
33
35
34
@abc .abstractmethod
36
35
def process (user_event ):
37
36
pass
38
37
39
38
40
- class BatchEventProcessor (EventProcessor ):
39
+ class BatchEventProcessor (BaseEventProcessor ):
41
40
"""
42
- BatchEventProcessor is a batched implementation of the EventProcessor.
43
-
41
+ BatchEventProcessor is a batched implementation of the BaseEventProcessor.
44
42
The BatchEventProcessor maintains a single consumer thread that pulls events off of
45
43
the blocking queue and buffers them for either a configured batch size or for a
46
44
maximum duration before the resulting LogEvent is sent to the EventDispatcher.
@@ -55,22 +53,23 @@ class BatchEventProcessor(EventProcessor):
55
53
LOCK = threading .Lock ()
56
54
57
55
def __init__ (self ,
58
- event_dispatcher ,
59
- logger ,
60
- start_on_init = False ,
61
- event_queue = None ,
62
- batch_size = None ,
63
- flush_interval = None ,
64
- timeout_interval = None ,
65
- notification_center = None ):
56
+ event_dispatcher ,
57
+ logger ,
58
+ start_on_init = False ,
59
+ event_queue = None ,
60
+ batch_size = None ,
61
+ flush_interval = None ,
62
+ timeout_interval = None ,
63
+ notification_center = None ):
66
64
""" EventProcessor init method to configure event batching.
65
+
67
66
Args:
68
67
event_dispatcher: Provides a dispatch_event method which if given a URL and params sends a request to it.
69
68
logger: Provides a log method to log messages. By default nothing would be logged.
70
69
start_on_init: Optional boolean param which starts the consumer thread if set to True.
71
- By default thread does not start unless 'start' method is called .
70
+ Default value is False .
72
71
event_queue: Optional component which accumulates the events until dispacthed.
73
- batch_size: Optional param which defines the upper limit of the number of events in event_queue after which
72
+ batch_size: Optional param which defines the upper limit on the number of events in event_queue after which
74
73
the event_queue will be flushed.
75
74
flush_interval: Optional floating point number representing time interval in seconds after which event_queue will
76
75
be flushed.
@@ -89,9 +88,8 @@ def __init__(self,
89
88
self .timeout_interval = timedelta (seconds = timeout_interval ) \
90
89
if self ._validate_intantiation_props (timeout_interval , 'timeout_interval' ) \
91
90
else self ._DEFAULT_TIMEOUT_INTERVAL
92
-
93
91
self .notification_center = notification_center
94
- self . _disposed = False
92
+
95
93
self ._is_started = False
96
94
self ._current_batch = list ()
97
95
@@ -100,13 +98,22 @@ def __init__(self,
100
98
101
99
@property
102
100
def is_started (self ):
101
+ """ Property to check if consumer thread is alive or not. """
103
102
return self ._is_started
104
103
105
- @property
106
- def disposed (self ):
107
- return self ._disposed
108
-
109
104
def _validate_intantiation_props (self , prop , prop_name ):
105
+ """ Method to determine if instantiation properties like batch_size, flush_interval
106
+ and timeout_interval are valid.
107
+
108
+ Args:
109
+ prop: Property value that needs to be validated.
110
+ prop_name: Property name.
111
+
112
+ Returns:
113
+ False if property value is None or less than 1 or not a finite number.
114
+ False if property name is batch_size and value is a floating point number.
115
+ True otherwise.
116
+ """
110
117
if (prop_name == 'batch_size' and not isinstance (prop , int )) or prop is None or prop < 1 or \
111
118
not validator .is_finite_number (prop ):
112
119
self .logger .info ('Using default value for {}.' .format (prop_name ))
@@ -115,13 +122,22 @@ def _validate_intantiation_props(self, prop, prop_name):
115
122
return True
116
123
117
124
def _get_time (self , _time = None ):
125
+ """ Method to return rounded off time as integer in seconds. If _time is None, uses current time.
126
+
127
+ Args:
128
+ _time: time in seconds that needs to be rounded off.
129
+
130
+ Returns:
131
+ Integer time in seconds.
132
+ """
118
133
if _time is None :
119
134
return int (round (time .time ()))
120
135
121
136
return int (round (_time ))
122
137
123
138
def start (self ):
124
- if self .is_started and not self .disposed :
139
+ """ Starts the batch processing thread to batch events. """
140
+ if self .is_started :
125
141
self .logger .warning ('Service already started' )
126
142
return
127
143
@@ -133,7 +149,9 @@ def start(self):
133
149
self ._is_started = True
134
150
135
151
def _run (self ):
136
- """ Scheduler method that periodically flushes events queue. """
152
+ """ Triggered as part of the thread which batches events or flushes event_queue and sleeps
153
+ periodically if queue is empty.
154
+ """
137
155
try :
138
156
while True :
139
157
if self ._get_time () > self .flushing_interval_deadline :
@@ -143,7 +161,6 @@ def _run(self):
143
161
item = self .event_queue .get (True , 0.05 )
144
162
145
163
except queue .Empty :
146
- self .logger .debug ('Empty queue, sleeping for 50ms.' )
147
164
time .sleep (0.05 )
148
165
continue
149
166
0 commit comments