Skip to content

[FSSDK-11638] cleanups in event processing #1073

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

Merged
merged 2 commits into from
Jun 25, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/event_processor/batch_event_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ export class BatchEventProcessor extends BaseService implements EventProcessor {
}

private async readEventCountInStore(store: Store<EventWithId>): Promise<void> {
if (this.eventCountInStore !== undefined) {
return;
}

try {
const keys = await store.getKeys();
this.eventCountInStore = keys.length;
Expand Down
36 changes: 15 additions & 21 deletions lib/event_processor/event_builder/log_event.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
import { describe, it, expect } from 'vitest';

import {
buildConversionEventV1,
buildImpressionEventV1,
makeEventBatch,
} from './log_event';

import { ImpressionEvent, ConversionEvent } from './user_event';

describe('buildImpressionEventV1', () => {
it('should build an ImpressionEventV1 when experiment and variation are defined', () => {
describe('makeEventBatch', () => {
it('should build a batch with single impression event when experiment and variation are defined', () => {
const impressionEvent: ImpressionEvent = {
type: 'impression',
timestamp: 69,
Expand Down Expand Up @@ -65,7 +63,7 @@ describe('buildImpressionEventV1', () => {
enabled: true,
}

const result = buildImpressionEventV1(impressionEvent)
const result = makeEventBatch([impressionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -123,7 +121,7 @@ describe('buildImpressionEventV1', () => {
})
})

it('should build an ImpressionEventV1 when experiment and variation are not defined', () => {
it('should build a batch with simlge impression event when experiment and variation are not defined', () => {
const impressionEvent: ImpressionEvent = {
type: 'impression',
timestamp: 69,
Expand Down Expand Up @@ -164,7 +162,7 @@ describe('buildImpressionEventV1', () => {
enabled: true,
}

const result = buildImpressionEventV1(impressionEvent)
const result = makeEventBatch([impressionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -220,11 +218,9 @@ describe('buildImpressionEventV1', () => {
},
],
})
})
})
});

describe('buildConversionEventV1', () => {
it('should build a ConversionEventV1 when tags object is defined', () => {
it('should build a batch with single conversion event when tags object is defined', () => {
const conversionEvent: ConversionEvent = {
type: 'conversion',
timestamp: 69,
Expand Down Expand Up @@ -260,7 +256,7 @@ describe('buildConversionEventV1', () => {
value: 123,
}

const result = buildConversionEventV1(conversionEvent)
const result = makeEventBatch([conversionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -311,7 +307,7 @@ describe('buildConversionEventV1', () => {
})
})

it('should build a ConversionEventV1 when tags object is undefined', () => {
it('should build a batch with single conversion event when when tags object is undefined', () => {
const conversionEvent: ConversionEvent = {
type: 'conversion',
timestamp: 69,
Expand Down Expand Up @@ -343,7 +339,7 @@ describe('buildConversionEventV1', () => {
value: 123,
}

const result = buildConversionEventV1(conversionEvent)
const result = makeEventBatch([conversionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -390,7 +386,7 @@ describe('buildConversionEventV1', () => {
})
})

it('should build a ConversionEventV1 when event id is null', () => {
it('should build a batch with single conversion event when event id is null', () => {
const conversionEvent: ConversionEvent = {
type: 'conversion',
timestamp: 69,
Expand Down Expand Up @@ -422,7 +418,7 @@ describe('buildConversionEventV1', () => {
value: 123,
}

const result = buildConversionEventV1(conversionEvent)
const result = makeEventBatch([conversionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -469,7 +465,7 @@ describe('buildConversionEventV1', () => {
})
})

it('should include revenue and value if they are 0', () => {
it('should include revenue and value for conversion events if they are 0', () => {
const conversionEvent: ConversionEvent = {
type: 'conversion',
timestamp: 69,
Expand Down Expand Up @@ -505,7 +501,7 @@ describe('buildConversionEventV1', () => {
value: 0,
}

const result = buildConversionEventV1(conversionEvent)
const result = makeEventBatch([conversionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -591,7 +587,7 @@ describe('buildConversionEventV1', () => {
value: 123,
}

const result = buildConversionEventV1(conversionEvent)
const result = makeEventBatch([conversionEvent])
expect(result).toEqual({
client_name: 'node-sdk',
client_version: '3.0.0',
Expand Down Expand Up @@ -635,9 +631,7 @@ describe('buildConversionEventV1', () => {
],
})
})
})

describe('makeEventBatch', () => {
it('should batch Conversion and Impression events together', () => {
const conversionEvent: ConversionEvent = {
type: 'conversion',
Expand Down
42 changes: 0 additions & 42 deletions lib/event_processor/event_builder/log_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,48 +214,6 @@ function makeVisitor(data: ImpressionEvent | ConversionEvent): Visitor {
return visitor
}

/**
* Event for usage with v1 logtier
*
* @export
* @interface EventBuilderV1
*/
export function buildImpressionEventV1(data: ImpressionEvent): EventBatch {
const visitor = makeVisitor(data)
visitor.snapshots.push(makeDecisionSnapshot(data))

return {
client_name: data.context.clientName,
client_version: data.context.clientVersion,

account_id: data.context.accountId,
project_id: data.context.projectId,
revision: data.context.revision,
anonymize_ip: data.context.anonymizeIP,
enrich_decisions: true,

visitors: [visitor],
}
}

export function buildConversionEventV1(data: ConversionEvent): EventBatch {
const visitor = makeVisitor(data)
visitor.snapshots.push(makeConversionSnapshot(data))

return {
client_name: data.context.clientName,
client_version: data.context.clientVersion,

account_id: data.context.accountId,
project_id: data.context.projectId,
revision: data.context.revision,
anonymize_ip: data.context.anonymizeIP,
enrich_decisions: true,

visitors: [visitor],
}
}

export function buildLogEvent(events: UserEvent[]): LogEvent {
return {
url: 'https://logx.optimizely.com/v1/events',
Expand Down
104 changes: 59 additions & 45 deletions lib/event_processor/event_builder/user_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ type EventContext = {
botFiltering?: boolean;
}

export type BaseUserEvent = {
type: 'impression' | 'conversion';
type EventType = 'impression' | 'conversion';


export type BaseUserEvent<T extends EventType> = {
type: T;
timestamp: number;
uuid: string;
context: EventContext;
Expand All @@ -55,9 +58,7 @@ export type BaseUserEvent = {
};
};

export type ImpressionEvent = BaseUserEvent & {
type: 'impression';

export type ImpressionEvent = BaseUserEvent<'impression'> & {
layer: {
id: string | null;
} | null;
Expand All @@ -79,9 +80,7 @@ export type ImpressionEvent = BaseUserEvent & {
cmabUuid?: string;
};

export type ConversionEvent = BaseUserEvent & {
type: 'conversion';

export type ConversionEvent = BaseUserEvent<'conversion'> & {
event: {
id: string | null;
key: string;
Expand All @@ -108,6 +107,42 @@ export const areEventContextsEqual = (eventA: UserEvent, eventB: UserEvent): boo
)
}

const buildBaseEvent = <T extends EventType>({
configObj,
userId,
userAttributes,
clientEngine,
clientVersion,
type,
}: {
configObj: ProjectConfig;
userId: string;
userAttributes?: UserAttributes;
clientEngine: string;
clientVersion: string;
type: T;
}): BaseUserEvent<T> => {
return {
type,
timestamp: fns.currentTimestamp(),
uuid: fns.uuid(),
context: {
accountId: configObj.accountId,
projectId: configObj.projectId,
revision: configObj.revision,
clientName: clientEngine,
clientVersion: clientVersion,
anonymizeIP: configObj.anonymizeIP || false,
botFiltering: configObj.botFiltering,
},
user: {
id: userId,
attributes: buildVisitorAttributes(configObj, userAttributes),
},
};

}

export type ImpressionConfig = {
decisionObj: DecisionObj;
userId: string;
Expand All @@ -119,7 +154,6 @@ export type ImpressionConfig = {
configObj: ProjectConfig;
}


/**
* Creates an ImpressionEvent object from decision data
* @param {ImpressionConfig} config
Expand All @@ -146,24 +180,14 @@ export const buildImpressionEvent = function({
const layerId = experimentId !== null ? getLayerId(configObj, experimentId) : null;

return {
type: 'impression',
timestamp: fns.currentTimestamp(),
uuid: fns.uuid(),

user: {
id: userId,
attributes: buildVisitorAttributes(configObj, userAttributes),
},

context: {
accountId: configObj.accountId,
projectId: configObj.projectId,
revision: configObj.revision,
clientName: clientEngine,
clientVersion: clientVersion,
anonymizeIP: configObj.anonymizeIP || false,
botFiltering: configObj.botFiltering,
},
...buildBaseEvent({
configObj,
userId,
userAttributes,
clientEngine,
clientVersion,
type: 'impression',
}),

layer: {
id: layerId,
Expand Down Expand Up @@ -218,24 +242,14 @@ export const buildConversionEvent = function({
const eventValue = eventTags ? eventTagUtils.getEventValue(eventTags, logger) : null;

return {
type: 'conversion',
timestamp: fns.currentTimestamp(),
uuid: fns.uuid(),

user: {
id: userId,
attributes: buildVisitorAttributes(configObj, userAttributes),
},

context: {
accountId: configObj.accountId,
projectId: configObj.projectId,
revision: configObj.revision,
clientName: clientEngine,
clientVersion: clientVersion,
anonymizeIP: configObj.anonymizeIP || false,
botFiltering: configObj.botFiltering,
},
...buildBaseEvent({
configObj,
userId,
userAttributes,
clientEngine,
clientVersion,
type: 'conversion',
}),

event: {
id: eventId,
Expand Down
Loading