Skip to content

Commit

Permalink
feat: feature lifecycle metrics from event bus (#6789)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwasniew committed Apr 5, 2024
1 parent 28a3a06 commit e868c32
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ import {
type IUnleashConfig,
} from '../../types';
import { createFakeFeatureLifecycleService } from './createFeatureLifecycle';
import EventEmitter from 'events';

function ms(timeMs) {
return new Promise((resolve) => setTimeout(resolve, timeMs));
}

test('can insert and read lifecycle stages', async () => {
const eventBus = new EventEmitter();
const { featureLifecycleService, eventStore, environmentStore } =
createFakeFeatureLifecycleService({
flagResolver: { isEnabled: () => true },
eventBus,
} as unknown as IUnleashConfig);
const featureName = 'testFeature';

async function emitMetricsEvent(environment: string) {
await eventStore.emit(CLIENT_METRICS, { featureName, environment });
await eventBus.emit(CLIENT_METRICS, { featureName, environment });
await ms(1);
}

Expand Down Expand Up @@ -68,9 +71,11 @@ test('can insert and read lifecycle stages', async () => {
});

test('ignores lifecycle state updates when flag disabled', async () => {
const eventBus = new EventEmitter();
const { featureLifecycleService, eventStore, environmentStore } =
createFakeFeatureLifecycleService({
flagResolver: { isEnabled: () => false },
eventBus,
} as unknown as IUnleashConfig);
const featureName = 'testFeature';

Expand All @@ -82,7 +87,7 @@ test('ignores lifecycle state updates when flag disabled', async () => {

await eventStore.emit(FEATURE_CREATED, { featureName });
await eventStore.emit(FEATURE_COMPLETED, { featureName });
await eventStore.emit(CLIENT_METRICS, {
await eventBus.emit(CLIENT_METRICS, {
featureName,
environment: 'development',
});
Expand Down
11 changes: 9 additions & 2 deletions src/lib/features/feature-lifecycle/feature-lifecycle-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
FeatureLifecycleView,
IFeatureLifecycleStore,
} from './feature-lifecycle-store-type';
import type EventEmitter from 'events';

export class FeatureLifecycleService {
private eventStore: IEventStore;
Expand All @@ -22,6 +23,8 @@ export class FeatureLifecycleService {

private flagResolver: IFlagResolver;

private eventBus: EventEmitter;

constructor(
{
eventStore,
Expand All @@ -32,12 +35,16 @@ export class FeatureLifecycleService {
environmentStore: IEnvironmentStore;
featureLifecycleStore: IFeatureLifecycleStore;
},
{ flagResolver }: Pick<IUnleashConfig, 'flagResolver'>,
{
flagResolver,
eventBus,
}: Pick<IUnleashConfig, 'flagResolver' | 'eventBus'>,
) {
this.eventStore = eventStore;
this.featureLifecycleStore = featureLifecycleStore;
this.environmentStore = environmentStore;
this.flagResolver = flagResolver;
this.eventBus = eventBus;
}

private async checkEnabled(fn: () => Promise<void>) {
Expand All @@ -53,7 +60,7 @@ export class FeatureLifecycleService {
this.featureInitialized(event.featureName),
);
});
this.eventStore.on(CLIENT_METRICS, async (event) => {
this.eventBus.on(CLIENT_METRICS, async (event) => {
await this.checkEnabled(() =>
this.featureReceivedMetrics(
event.featureName,
Expand Down
19 changes: 17 additions & 2 deletions src/lib/features/feature-lifecycle/feature-lifecycle.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import {
setupAppWithAuth,
} from '../../../test/e2e/helpers/test-helper';
import getLogger from '../../../test/fixtures/no-logger';
import {
FEATURE_ARCHIVED,
FEATURE_CREATED,
type IEventStore,
} from '../../types';

let app: IUnleashTest;
let db: ITestDb;
let eventStore: IEventStore;

beforeAll(async () => {
db = await dbInit('feature_lifecycle', getLogger);
Expand All @@ -21,6 +27,7 @@ beforeAll(async () => {
},
db.rawDatabase,
);
eventStore = db.stores.eventStore;

await app.request
.post(`/auth/demo/login`)
Expand All @@ -43,10 +50,18 @@ const getFeatureLifecycle = async (featureName: string, expectedCode = 200) => {
.expect(expectedCode);
};

function ms(timeMs) {
return new Promise((resolve) => setTimeout(resolve, timeMs));
}

test('should return lifecycle stages', async () => {
await app.createFeature('my_feature_a');
await eventStore.emit(FEATURE_CREATED, { featureName: 'my_feature_a' });
await eventStore.emit(FEATURE_ARCHIVED, { featureName: 'my_feature_a' });

const { body } = await getFeatureLifecycle('my_feature_a');

expect(body).toEqual([]);
expect(body).toEqual([
{ stage: 'initial', enteredStageAt: expect.any(String) },
{ stage: 'archived', enteredStageAt: expect.any(String) },
]);
});

0 comments on commit e868c32

Please sign in to comment.