Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ [RUM-2445] do not buffer early recorder API calls #2563

Merged
merged 1 commit into from Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions packages/rum-core/src/boot/rumPublicApi.spec.ts
Expand Up @@ -1015,18 +1015,18 @@ describe('rum public api', () => {
)
})

it('api calls before init are performed after onRumStart', () => {
// in order to let recording initial state to be defined by init configuration
const callOrders: string[] = []
spyOn(recorderApi, 'start').and.callFake(() => callOrders.push('start'))
spyOn(recorderApi, 'stop').and.callFake(() => callOrders.push('stop'))
recorderApiOnRumStartSpy.and.callFake(() => callOrders.push('onRumStart'))
it('public api calls are forwarded to the recorder api', () => {
spyOn(recorderApi, 'start')
spyOn(recorderApi, 'stop')
spyOn(recorderApi, 'getSessionReplayLink')

rumPublicApi.startSessionReplayRecording()
rumPublicApi.stopSessionReplayRecording()
rumPublicApi.init(DEFAULT_INIT_CONFIGURATION)
rumPublicApi.getSessionReplayLink()

expect(callOrders).toEqual(['onRumStart', 'start', 'stop'])
expect(recorderApi.start).toHaveBeenCalledTimes(1)
expect(recorderApi.stop).toHaveBeenCalledTimes(1)
expect(recorderApi.getSessionReplayLink).toHaveBeenCalledTimes(1)
})

it('is started with the default startSessionReplayRecordingManually', () => {
Expand Down
27 changes: 5 additions & 22 deletions packages/rum-core/src/boot/rumPublicApi.ts
Expand Up @@ -62,11 +62,7 @@ export interface RecorderApi {
) => void
isRecording: () => boolean
getReplayStats: (viewId: string) => ReplayStats | undefined
getSessionReplayLink: (
configuration: RumConfiguration,
sessionManager: RumSessionManager,
viewContexts: ViewContexts
) => string | undefined
getSessionReplayLink: () => string | undefined
}
interface RumPublicApiOptions {
ignoreInitIfSyntheticsWillInjectRum?: boolean
Expand Down Expand Up @@ -100,7 +96,6 @@ export function makeRumPublicApi(
let getInternalContextStrategy: StartRumResult['getInternalContext'] = () => undefined
let getInitConfigurationStrategy = (): InitConfiguration | undefined => undefined
let stopSessionStrategy: () => void = noop
let getSessionReplayLinkStrategy: () => string | undefined = () => undefined

let bufferApiCalls = new BoundedBuffer()
let addTimingStrategy: StartRumResult['addTiming'] = (name, time = timeStampNow()) => {
Expand All @@ -122,14 +117,6 @@ export function makeRumPublicApi(
bufferApiCalls.add(() => addErrorStrategy(providedError, commonContext))
}

let recorderStartStrategy: typeof recorderApi.start = () => {
bufferApiCalls.add(() => recorderStartStrategy())
}

let recorderStopStrategy: typeof recorderApi.stop = () => {
bufferApiCalls.add(() => recorderStopStrategy())
}

let addFeatureFlagEvaluationStrategy: StartRumResult['addFeatureFlagEvaluation'] = (key: string, value: any) => {
bufferApiCalls.add(() => addFeatureFlagEvaluationStrategy(key, value))
}
Expand Down Expand Up @@ -245,10 +232,6 @@ export function makeRumPublicApi(
? (streamId) => createDeflateEncoder(configuration, deflateWorker!, streamId)
: createIdentityEncoder
)
getSessionReplayLinkStrategy = () =>
recorderApi.getSessionReplayLink(configuration, startRumResults.session, startRumResults.viewContexts)
recorderStartStrategy = recorderApi.start
recorderStopStrategy = recorderApi.stop
;({
startView: startViewStrategy,
addAction: addActionStrategy,
Expand Down Expand Up @@ -341,16 +324,16 @@ export function makeRumPublicApi(
stopSessionStrategy()
}),

startSessionReplayRecording: monitor(() => recorderStartStrategy()),
stopSessionReplayRecording: monitor(() => recorderStopStrategy()),

/**
* This feature is currently in beta. For more information see the full [feature flag tracking guide](https://docs.datadoghq.com/real_user_monitoring/feature_flag_tracking/).
*/
addFeatureFlagEvaluation: monitor((key: string, value: any) => {
addFeatureFlagEvaluationStrategy(sanitize(key)!, sanitize(value))
}),
getSessionReplayLink: monitor(() => getSessionReplayLinkStrategy()),

getSessionReplayLink: monitor(() => recorderApi.getSessionReplayLink()),
startSessionReplayRecording: monitor(() => recorderApi.start()),
stopSessionReplayRecording: monitor(() => recorderApi.stop()),
})

return rumPublicApi
Expand Down
17 changes: 17 additions & 0 deletions packages/rum-slim/src/boot/stubRecorderApi.ts
@@ -0,0 +1,17 @@
import { noop } from '@datadog/browser-core'
import type { LifeCycle, RumConfiguration } from '@datadog/browser-rum-core'
import { getSessionReplayLink } from '../domain/getSessionReplayLink'

export function makeStubRecorderApi() {
let getSessionReplayLinkStrategy = noop as () => string | undefined
return {
start: noop,
stop: noop,
onRumStart(_lifeCycle: LifeCycle, configuration: RumConfiguration) {
getSessionReplayLinkStrategy = () => getSessionReplayLink(configuration)
},
isRecording: () => false,
getReplayStats: () => undefined,
getSessionReplayLink: () => getSessionReplayLinkStrategy(),
}
}
13 changes: 3 additions & 10 deletions packages/rum-slim/src/entries/main.ts
@@ -1,8 +1,8 @@
// Keep the following in sync with packages/rum/src/entries/main.ts
import { defineGlobal, getGlobalObject, noop } from '@datadog/browser-core'
import { defineGlobal, getGlobalObject } from '@datadog/browser-core'
import type { RumPublicApi } from '@datadog/browser-rum-core'
import { makeRumPublicApi, startRum } from '@datadog/browser-rum-core'
import { getSessionReplayLink } from '../domain/getSessionReplayLink'
import { makeStubRecorderApi } from '../boot/stubRecorderApi'

export {
CommonProperties,
Expand All @@ -27,14 +27,7 @@ export {
} from '@datadog/browser-rum-core'
export { DefaultPrivacyLevel } from '@datadog/browser-core'

export const datadogRum = makeRumPublicApi(startRum, {
start: noop,
stop: noop,
onRumStart: noop,
isRecording: () => false,
getReplayStats: () => undefined,
getSessionReplayLink,
})
export const datadogRum = makeRumPublicApi(startRum, makeStubRecorderApi())

interface BrowserWindow extends Window {
DD_RUM?: RumPublicApi
Expand Down
7 changes: 5 additions & 2 deletions packages/rum/src/boot/recorderApi.ts
Expand Up @@ -74,12 +74,12 @@ export function makeRecorderApi(
let stopStrategy = () => {
state = { status: RecorderStatus.Stopped }
}
let getSessionReplayLinkStrategy = noop as () => string | undefined

return {
start: () => startStrategy(),
stop: () => stopStrategy(),
getSessionReplayLink: (configuration, sessionManager, viewContexts) =>
getSessionReplayLink(configuration, sessionManager, viewContexts, state.status !== RecorderStatus.Stopped),
getSessionReplayLink: () => getSessionReplayLinkStrategy(),
onRumStart: (
lifeCycle: LifeCycle,
configuration: RumConfiguration,
Expand Down Expand Up @@ -178,6 +178,9 @@ export function makeRecorderApi(
}
}

getSessionReplayLinkStrategy = () =>
getSessionReplayLink(configuration, sessionManager, viewContexts, state.status !== RecorderStatus.Stopped)

if (state.status === RecorderStatus.IntentToStart) {
startStrategy()
}
Expand Down