diff --git a/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.spec.ts b/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.spec.ts index 898b8e0997..8f7266e759 100644 --- a/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.spec.ts +++ b/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.spec.ts @@ -2,18 +2,25 @@ import type { Context } from '@datadog/browser-core' import { noop } from '@datadog/browser-core' import type { RumResourceEvent } from '../../../rumEvent.types' import { RumEventType } from '../../../rawRumEvent.types' +import type { Clock } from '../../../../../core/test/specHelper' +import { mockClock } from '../../../../../core/test/specHelper' import { LifeCycle, LifeCycleEventType } from '../../lifeCycle' -import { trackViewEventCounts } from './trackViewEventCounts' +import { KEEP_TRACKING_EVENT_COUNTS_AFTER_VIEW_DELAY, trackViewEventCounts } from './trackViewEventCounts' describe('trackViewEventCounts', () => { const VIEW_ID = 'a' const OTHER_VIEW_ID = 'b' let lifeCycle: LifeCycle + let clock: Clock | undefined beforeEach(() => { lifeCycle = new LifeCycle() }) + afterEach(() => { + if (clock) clock.cleanup() + }) + it('initializes eventCounts to 0', () => { const { eventCounts } = trackViewEventCounts(lifeCycle, VIEW_ID, noop) @@ -42,6 +49,23 @@ describe('trackViewEventCounts', () => { expect(eventCounts.resourceCount).toBe(0) }) + it('when calling scheduleStop, it keeps counting events for a bit of time', () => { + clock = mockClock() + const { scheduleStop, eventCounts } = trackViewEventCounts(lifeCycle, VIEW_ID, noop) + + scheduleStop() + + clock.tick(KEEP_TRACKING_EVENT_COUNTS_AFTER_VIEW_DELAY - 1) + notifyResourceEvent() + + expect(eventCounts.resourceCount).toBe(1) + + clock.tick(1) + notifyResourceEvent() + + expect(eventCounts.resourceCount).toBe(1) + }) + function notifyResourceEvent(viewId = VIEW_ID) { lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, { type: RumEventType.RESOURCE, diff --git a/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.ts b/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.ts index e21613f385..e5023c7cf5 100644 --- a/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.ts +++ b/packages/rum-core/src/domain/rumEventsCollection/view/trackViewEventCounts.ts @@ -1,6 +1,21 @@ +import { ONE_MINUTE } from '@datadog/browser-core' import type { LifeCycle } from '../../lifeCycle' import { trackEventCounts } from '../../trackEventCounts' +// Arbitrary delay for stopping event counting after the view ends. Ideally, we would not stop and +// keep counting events until the end of the session. But this might have a small performance impact +// if there are many many views: we would need to go through each event to see if the related view +// matches. So let's have a fairly short delay to avoid impacting performances too much. +// +// In the future, we could have views stored in a data structure similar to ContextHistory. Whenever +// a child event is collected, we could look into this history to find the matching view and +// increase the associated and increase its counter. Having a centralized data structure for it +// would allow us to look for views more efficiently. +// +// For now, having a small cleanup delay will already improve the situation in most cases. + +export const KEEP_TRACKING_EVENT_COUNTS_AFTER_VIEW_DELAY = 5 * ONE_MINUTE + export function trackViewEventCounts(lifeCycle: LifeCycle, viewId: string, onChange: () => void) { const { stop, eventCounts } = trackEventCounts({ lifeCycle, @@ -8,5 +23,10 @@ export function trackViewEventCounts(lifeCycle: LifeCycle, viewId: string, onCha onChange, }) - return { stop, eventCounts } + return { + scheduleStop: () => { + setTimeout(stop, KEEP_TRACKING_EVENT_COUNTS_AFTER_VIEW_DELAY) + }, + eventCounts, + } } diff --git a/packages/rum-core/src/domain/rumEventsCollection/view/trackViews.ts b/packages/rum-core/src/domain/rumEventsCollection/view/trackViews.ts index f69f5878cc..033e3a1680 100644 --- a/packages/rum-core/src/domain/rumEventsCollection/view/trackViews.ts +++ b/packages/rum-core/src/domain/rumEventsCollection/view/trackViews.ts @@ -229,7 +229,11 @@ function newView( viewMetrics, } = trackViewMetrics(lifeCycle, domMutationObservable, configuration, scheduleViewUpdate, loadingType, startClocks) - const { stop: stopEventCountsTracking, eventCounts } = trackViewEventCounts(lifeCycle, id, scheduleViewUpdate) + const { scheduleStop: scheduleStopEventCountsTracking, eventCounts } = trackViewEventCounts( + lifeCycle, + id, + scheduleViewUpdate + ) // Initial view update triggerViewUpdate() @@ -269,7 +273,7 @@ function newView( endClocks = clocks lifeCycle.notify(LifeCycleEventType.VIEW_ENDED, { endClocks }) stopViewMetricsTracking() - stopEventCountsTracking() + scheduleStopEventCountsTracking() }, triggerUpdate() { // cancel any pending view updates execution