mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-28 00:06:53 +01:00
feat: backfill current stage on startup (#7057)
This commit is contained in:
parent
701c845f09
commit
6b59b30846
@ -16,6 +16,8 @@ export class FakeFeatureLifecycleStore implements IFeatureLifecycleStore {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async backfill() {}
|
||||||
|
|
||||||
private async insertOne(
|
private async insertOne(
|
||||||
featureLifecycleStage: FeatureLifecycleStage,
|
featureLifecycleStage: FeatureLifecycleStage,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -87,6 +87,7 @@ export class FeatureLifecycleService extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listen() {
|
listen() {
|
||||||
|
void this.checkEnabled(() => this.featureLifecycleStore.backfill());
|
||||||
this.eventStore.on(FEATURE_CREATED, async (event) => {
|
this.eventStore.on(FEATURE_CREATED, async (event) => {
|
||||||
await this.checkEnabled(() =>
|
await this.checkEnabled(() =>
|
||||||
this.featureInitialized(event.featureName),
|
this.featureInitialized(event.featureName),
|
||||||
|
@ -21,4 +21,5 @@ export interface IFeatureLifecycleStore {
|
|||||||
stageExists(stage: FeatureLifecycleStage): Promise<boolean>;
|
stageExists(stage: FeatureLifecycleStage): Promise<boolean>;
|
||||||
delete(feature: string): Promise<void>;
|
delete(feature: string): Promise<void>;
|
||||||
deleteStage(stage: FeatureLifecycleStage): Promise<void>;
|
deleteStage(stage: FeatureLifecycleStage): Promise<void>;
|
||||||
|
backfill(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,16 @@ export class FeatureLifecycleStore implements IFeatureLifecycleStore {
|
|||||||
this.db = db;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async backfill(): Promise<void> {
|
||||||
|
await this.db.raw(`
|
||||||
|
INSERT INTO feature_lifecycles (feature, stage, created_at)
|
||||||
|
SELECT features.name, 'initial', features.created_at
|
||||||
|
FROM features
|
||||||
|
LEFT JOIN feature_lifecycles ON features.name = feature_lifecycles.feature
|
||||||
|
WHERE feature_lifecycles.feature IS NULL
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
async insert(
|
async insert(
|
||||||
featureLifecycleStages: FeatureLifecycleStage[],
|
featureLifecycleStages: FeatureLifecycleStage[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
FEATURE_CREATED,
|
FEATURE_CREATED,
|
||||||
FEATURE_REVIVED,
|
FEATURE_REVIVED,
|
||||||
type IEventStore,
|
type IEventStore,
|
||||||
|
type IFeatureLifecycleStore,
|
||||||
type StageName,
|
type StageName,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import type EventEmitter from 'events';
|
import type EventEmitter from 'events';
|
||||||
@ -24,6 +25,7 @@ import type { IFeatureLifecycleReadModel } from './feature-lifecycle-read-model-
|
|||||||
let app: IUnleashTest;
|
let app: IUnleashTest;
|
||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
let featureLifecycleService: FeatureLifecycleService;
|
let featureLifecycleService: FeatureLifecycleService;
|
||||||
|
let featureLifecycleStore: IFeatureLifecycleStore;
|
||||||
let eventStore: IEventStore;
|
let eventStore: IEventStore;
|
||||||
let eventBus: EventEmitter;
|
let eventBus: EventEmitter;
|
||||||
let featureLifecycleReadModel: IFeatureLifecycleReadModel;
|
let featureLifecycleReadModel: IFeatureLifecycleReadModel;
|
||||||
@ -45,6 +47,7 @@ beforeAll(async () => {
|
|||||||
eventBus = app.config.eventBus;
|
eventBus = app.config.eventBus;
|
||||||
featureLifecycleService = app.services.featureLifecycleService;
|
featureLifecycleService = app.services.featureLifecycleService;
|
||||||
featureLifecycleReadModel = new FeatureLifecycleReadModel(db.rawDatabase);
|
featureLifecycleReadModel = new FeatureLifecycleReadModel(db.rawDatabase);
|
||||||
|
featureLifecycleStore = db.stores.featureLifecycleStore;
|
||||||
|
|
||||||
await app.request
|
await app.request
|
||||||
.post(`/auth/demo/login`)
|
.post(`/auth/demo/login`)
|
||||||
@ -186,3 +189,20 @@ test('should be able to toggle between completed/uncompleted', async () => {
|
|||||||
|
|
||||||
expect(body).toEqual([]);
|
expect(body).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should backfill initial stage when no stages', async () => {
|
||||||
|
await app.createFeature('my_feature_c');
|
||||||
|
|
||||||
|
await featureLifecycleStore.delete('my_feature_c');
|
||||||
|
|
||||||
|
const currentStage = await getCurrentStage('my_feature_c');
|
||||||
|
expect(currentStage).toBe(undefined);
|
||||||
|
|
||||||
|
await featureLifecycleStore.backfill();
|
||||||
|
|
||||||
|
const backfilledCurrentStage = await getCurrentStage('my_feature_c');
|
||||||
|
expect(backfilledCurrentStage).toEqual({
|
||||||
|
stage: 'initial',
|
||||||
|
enteredStageAt: expect.any(Date),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user