Skip to content

Commit 08b57eb

Browse files
authored
Merge pull request #48 from launchdarkly/eb/summary-events-debug-index
fix behavior of debug & index events
2 parents 108bf10 + 00fd2ef commit 08b57eb

File tree

2 files changed

+69
-26
lines changed

2 files changed

+69
-26
lines changed

ldclient/event_processor.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def make_output_events(self, events, summary):
6868
def make_output_event(self, e):
6969
kind = e['kind']
7070
if kind == 'feature':
71-
is_debug = (not e['trackEvents']) and (e.get('debugEventsUntilDate') is not None)
71+
is_debug = e.get('debug')
7272
out = {
7373
'kind': 'debug' if is_debug else 'feature',
7474
'creationDate': e['creationDate'],
@@ -78,7 +78,7 @@ def make_output_event(self, e):
7878
'default': e.get('default'),
7979
'prereqOf': e.get('prereqOf')
8080
}
81-
if self._inline_users:
81+
if self._inline_users or is_debug:
8282
out['user'] = self._user_filter.filter_user_props(e['user'])
8383
else:
8484
out['userKey'] = e['user'].get('key')
@@ -261,21 +261,37 @@ def _process_event(self, event):
261261
if self._disabled:
262262
return
263263

264-
# For each user we haven't seen before, we add an index event - unless this is already
265-
# an identify event for that user.
266-
user = event.get('user')
267-
if not self._config.inline_users_in_events and user and not self.notice_user(user):
268-
if event['kind'] != 'identify':
269-
ie = { 'kind': 'index', 'creationDate': event['creationDate'], 'user': user }
270-
self._buffer.add_event(ie)
271-
272264
# Always record the event in the summarizer.
273265
self._buffer.add_to_summary(event)
274266

275-
if self._should_track_full_event(event):
276-
# Queue the event as-is; we'll transform it into an output event when we're flushing
277-
# (to avoid doing that work on our main thread).
267+
# Decide whether to add the event to the payload. Feature events may be added twice, once for
268+
# the event (if tracked) and once for debugging.
269+
add_full_event = False
270+
add_debug_event = False
271+
add_index_event = False
272+
if event['kind'] == "feature":
273+
add_full_event = event['trackEvents']
274+
add_debug_event = self._should_debug_event(event)
275+
else:
276+
add_full_event = True
277+
278+
# For each user we haven't seen before, we add an index event - unless this is already
279+
# an identify event for that user.
280+
if not (add_full_event and self._config.inline_users_in_events):
281+
user = event.get('user')
282+
if user and not self.notice_user(user):
283+
if event['kind'] != 'identify':
284+
add_index_event = True
285+
286+
if add_index_event:
287+
ie = { 'kind': 'index', 'creationDate': event['creationDate'], 'user': user }
288+
self._buffer.add_event(ie)
289+
if add_full_event:
278290
self._buffer.add_event(event)
291+
if add_debug_event:
292+
debug_event = event.copy()
293+
debug_event['debug'] = True
294+
self._buffer.add_event(debug_event)
279295

280296
# Add to the set of users we've noticed, and return true if the user was already known to us.
281297
def notice_user(self, user):
@@ -288,19 +304,14 @@ def notice_user(self, user):
288304
self._user_keys[key] = True
289305
return False
290306

291-
def _should_track_full_event(self, event):
292-
if event['kind'] == 'feature':
293-
if event.get('trackEvents'):
307+
def _should_debug_event(self, event):
308+
debug_until = event.get('debugEventsUntilDate')
309+
if debug_until is not None:
310+
last_past = self._last_known_past_time
311+
now = int(time.time() * 1000)
312+
if debug_until > last_past and debug_until > now:
294313
return True
295-
debug_until = event.get('debugEventsUntilDate')
296-
if debug_until is not None:
297-
last_past = self._last_known_past_time
298-
now = int(time.time() * 1000)
299-
if debug_until > last_past and debug_until > now:
300-
return True
301-
return False
302-
else:
303-
return True
314+
return False
304315

305316
def _trigger_flush(self):
306317
if self._disabled:

testing/test_event_processor.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,20 @@ def test_user_is_filtered_in_feature_event():
175175
check_feature_event(output[0], e, False, filtered_user)
176176
check_summary_event(output[1])
177177

178+
def test_index_event_is_still_generated_if_inline_users_is_true_but_feature_event_is_not_tracked():
179+
setup_processor(Config(inline_users_in_events = True))
180+
181+
e = {
182+
'kind': 'feature', 'key': 'flagkey', 'version': 11, 'user': user,
183+
'variation': 1, 'value': 'value', 'default': 'default', 'trackEvents': False
184+
}
185+
ep.send_event(e)
186+
187+
output = flush_and_get_events()
188+
assert len(output) == 2
189+
check_index_event(output[0], e, user)
190+
check_summary_event(output[1])
191+
178192
def test_event_kind_is_debug_if_flag_is_temporarily_in_debug_mode():
179193
setup_processor(Config())
180194

@@ -189,9 +203,27 @@ def test_event_kind_is_debug_if_flag_is_temporarily_in_debug_mode():
189203
output = flush_and_get_events()
190204
assert len(output) == 3
191205
check_index_event(output[0], e, user)
192-
check_feature_event(output[1], e, True, None)
206+
check_feature_event(output[1], e, True, user)
193207
check_summary_event(output[2])
194208

209+
def test_event_can_be_both_tracked_and_debugged():
210+
setup_processor(Config())
211+
212+
future_time = now() + 100000
213+
e = {
214+
'kind': 'feature', 'key': 'flagkey', 'version': 11, 'user': user,
215+
'variation': 1, 'value': 'value', 'default': 'default',
216+
'trackEvents': True, 'debugEventsUntilDate': future_time
217+
}
218+
ep.send_event(e)
219+
220+
output = flush_and_get_events()
221+
assert len(output) == 4
222+
check_index_event(output[0], e, user)
223+
check_feature_event(output[1], e, False, None)
224+
check_feature_event(output[2], e, True, user)
225+
check_summary_event(output[3])
226+
195227
def test_debug_mode_expires_based_on_client_time_if_client_time_is_later_than_server_time():
196228
setup_processor(Config())
197229

0 commit comments

Comments
 (0)