Skip to content

Commit a3f665b

Browse files
✨ [RUM-10144] delay assembly
1 parent 92253a5 commit a3f665b

2 files changed

Lines changed: 55 additions & 20 deletions

File tree

packages/rum-core/src/domain/assembly.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,34 @@ describe('rum assembly', () => {
478478
})
479479
})
480480

481+
describe('global context', () => {
482+
it('applies global context to events', async () => {
483+
const { lifeCycle, globalContext, getRumEvents } = setupAssemblyTestWithDefaults()
484+
485+
globalContext.setContext({ foo: 'bar' })
486+
487+
notifyRawRumEvent(lifeCycle, {
488+
rawRumEvent: createRawRumEvent(RumEventType.ACTION),
489+
})
490+
491+
const rumEvents = await getRumEvents()
492+
expect(rumEvents[0].context).toEqual({ foo: 'bar' })
493+
})
494+
495+
it('applies global context to events generated before the global context is set', async () => {
496+
const { lifeCycle, globalContext, getRumEvents } = setupAssemblyTestWithDefaults()
497+
498+
notifyRawRumEvent(lifeCycle, {
499+
rawRumEvent: createRawRumEvent(RumEventType.ACTION),
500+
})
501+
502+
globalContext.setContext({ foo: 'bar' })
503+
504+
const rumEvents = await getRumEvents()
505+
expect(rumEvents[0].context).toEqual({ foo: 'bar' })
506+
})
507+
})
508+
481509
describe('event generation condition', () => {
482510
it('when tracked, it should generate event', async () => {
483511
const { lifeCycle, getRumEvents } = setupAssemblyTestWithDefaults()

packages/rum-core/src/domain/assembly.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import {
66
createEventRateLimiter,
77
isExperimentalFeatureEnabled,
88
ExperimentalFeature,
9+
BufferedObservable,
910
HookNames,
1011
DISCARDED,
1112
} from '@datadog/browser-core'
1213
import type { RumEventDomainContext } from '../domainContext.types'
1314
import { RumEventType } from '../rawRumEvent.types'
1415
import type { RumEvent } from '../rumEvent.types'
15-
import type { LifeCycle } from './lifeCycle'
16+
import type { LifeCycle, RawRumEventCollectedData } from './lifeCycle'
1617
import { LifeCycleEventType } from './lifeCycle'
1718
import type { RumConfiguration } from './configuration'
1819
import type { ModifiableFieldPaths } from './limitModification'
@@ -34,6 +35,10 @@ const ROOT_MODIFIABLE_FIELD_PATHS: ModifiableFieldPaths = {
3435
version: 'string',
3536
}
3637

38+
// The size of the buffer for events that are collected just after starting the assembly. This is a
39+
// bit arbitrary, but should be large enough to avoid dropping events in most cases.
40+
const BUFFERED_EVENT_SIZE = 100
41+
3742
let modifiableFieldPathsByEvent: { [key in RumEventType]: ModifiableFieldPaths }
3843

3944
export function startRumAssembly(
@@ -102,30 +107,32 @@ export function startRumAssembly(
102107
),
103108
}
104109

105-
lifeCycle.subscribe(
106-
LifeCycleEventType.RAW_RUM_EVENT_COLLECTED,
107-
({ startTime, duration, rawRumEvent, domainContext, customerContext }) => {
108-
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
109-
eventType: rawRumEvent.type,
110-
startTime,
111-
duration,
112-
})!
110+
const observable = new BufferedObservable<RawRumEventCollectedData>(BUFFERED_EVENT_SIZE)
113111

114-
if (defaultRumEventAttributes === DISCARDED) {
115-
return
116-
}
112+
lifeCycle.subscribe(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, (data) => observable.notify(data))
113+
114+
observable.subscribe(({ startTime, duration, rawRumEvent, domainContext, customerContext }) => {
115+
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
116+
eventType: rawRumEvent.type,
117+
startTime,
118+
duration,
119+
})!
120+
121+
if (defaultRumEventAttributes === DISCARDED) {
122+
return
123+
}
117124

118-
const serverRumEvent = combine(defaultRumEventAttributes, { context: customerContext }, rawRumEvent) as RumEvent &
119-
Context
125+
const serverRumEvent = combine(defaultRumEventAttributes, { context: customerContext }, rawRumEvent) as RumEvent &
126+
Context
120127

121-
if (shouldSend(serverRumEvent, configuration.beforeSend, domainContext, eventRateLimiters)) {
122-
if (isEmptyObject(serverRumEvent.context!)) {
123-
delete serverRumEvent.context
124-
}
125-
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, serverRumEvent)
128+
if (shouldSend(serverRumEvent, configuration.beforeSend, domainContext, eventRateLimiters)) {
129+
if (isEmptyObject(serverRumEvent.context!)) {
130+
delete serverRumEvent.context
126131
}
132+
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, serverRumEvent)
127133
}
128-
)
134+
})
135+
observable.unbuffer()
129136
}
130137

131138
function shouldSend(

0 commit comments

Comments
 (0)