Skip to content

Commit

Permalink
feat: transactional complete/uncomplete feature (#7451)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwasniew authored Jun 26, 2024
1 parent 7f6e29b commit d29230c
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 59 deletions.
73 changes: 33 additions & 40 deletions src/lib/features/feature-lifecycle/createFeatureLifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,41 @@ import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
import EventEmitter from 'events';

export const createFeatureLifecycleService = (
db: Db,
config: IUnleashConfig,
) => {
const { eventBus, getLogger, flagResolver } = config;
const eventStore = new EventStore(db, getLogger);
const featureLifecycleStore = new FeatureLifecycleStore(db);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
);
const featureTagStore = new FeatureTagStore(
db,
config.eventBus,
config.getLogger,
);
const eventService = new EventService(
{ eventStore, featureTagStore },
{ getLogger, eventBus: new EventEmitter() },
);
const featureLifecycleService = new FeatureLifecycleService(
{
eventStore,
featureLifecycleStore,
environmentStore,
featureEnvironmentStore,
},
{
eventService,
},
config,
);
export const createFeatureLifecycleService =
(config: IUnleashConfig) => (db: Db) => {
const { eventBus, getLogger, flagResolver } = config;
const eventStore = new EventStore(db, getLogger);
const featureLifecycleStore = new FeatureLifecycleStore(db);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
);
const featureTagStore = new FeatureTagStore(
db,
config.eventBus,
config.getLogger,
);
const eventService = new EventService(
{ eventStore, featureTagStore },
{ getLogger, eventBus: new EventEmitter() },
);
const featureLifecycleService = new FeatureLifecycleService(
{
eventStore,
featureLifecycleStore,
environmentStore,
featureEnvironmentStore,
},
{
eventService,
},
config,
);

return {
featureLifecycleService,
featureLifecycleStore,
eventStore,
environmentStore,
return featureLifecycleService;
};
};

export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
const eventStore = new FakeEventStore();
Expand Down
25 changes: 12 additions & 13 deletions src/lib/features/feature-lifecycle/feature-lifecycle-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Controller from '../../routes/controller';
import type { Request, Response } from 'express';
import { NotFoundError } from '../../error';
import type { IAuthRequest } from '../../routes/unleash-types';
import type { WithTransactional } from '../../db/transaction';

interface FeatureLifecycleParams {
projectId: string;
Expand All @@ -30,7 +31,7 @@ interface FeatureLifecycleParams {
const PATH = '/:projectId/features/:featureName/lifecycle';

export default class FeatureLifecycleController extends Controller {
private featureLifecycleService: FeatureLifecycleService;
private featureLifecycleService: WithTransactional<FeatureLifecycleService>;

private openApiService: OpenApiService;

Expand All @@ -39,12 +40,15 @@ export default class FeatureLifecycleController extends Controller {
constructor(
config: IUnleashConfig,
{
featureLifecycleService,
transactionalFeatureLifecycleService,
openApiService,
}: Pick<IUnleashServices, 'openApiService' | 'featureLifecycleService'>,
}: Pick<
IUnleashServices,
'openApiService' | 'transactionalFeatureLifecycleService'
>,
) {
super(config);
this.featureLifecycleService = featureLifecycleService;
this.featureLifecycleService = transactionalFeatureLifecycleService;
this.openApiService = openApiService;
this.flagResolver = config.flagResolver;

Expand Down Expand Up @@ -147,11 +151,8 @@ export default class FeatureLifecycleController extends Controller {

const status = req.body;

await this.featureLifecycleService.featureCompleted(
featureName,
projectId,
status,
req.audit,
await this.featureLifecycleService.transactional((service) =>
service.featureCompleted(featureName, projectId, status, req.audit),
);

res.status(200).end();
Expand All @@ -166,10 +167,8 @@ export default class FeatureLifecycleController extends Controller {
}
const { featureName, projectId } = req.params;

await this.featureLifecycleService.featureUncompleted(
featureName,
projectId,
req.audit,
await this.featureLifecycleService.transactional((service) =>
service.featureUncompleted(featureName, projectId, req.audit),
);

res.status(200).end();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ import {
type StageName,
} from '../../types';
import type EventEmitter from 'events';
import type { FeatureLifecycleService } from './feature-lifecycle-service';
import type { FeatureLifecycleCompletedSchema } from '../../openapi';
import { FeatureLifecycleReadModel } from './feature-lifecycle-read-model';
import type { IFeatureLifecycleReadModel } from './feature-lifecycle-read-model-type';
import { STAGE_ENTERED } from '../../metric-events';

let app: IUnleashTest;
let db: ITestDb;
let featureLifecycleService: FeatureLifecycleService;
let featureLifecycleStore: IFeatureLifecycleStore;
let eventStore: IEventStore;
let eventBus: EventEmitter;
Expand All @@ -43,7 +41,6 @@ beforeAll(async () => {
);
eventStore = db.stores.eventStore;
eventBus = app.config.eventBus;
featureLifecycleService = app.services.featureLifecycleService;
featureLifecycleReadModel = new FeatureLifecycleReadModel(
db.rawDatabase,
app.config.flagResolver,
Expand Down
10 changes: 7 additions & 3 deletions src/lib/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,12 @@ export const createServices = (
config.getLogger,
);

const { featureLifecycleService } = db
? createFeatureLifecycleService(db, config)
: createFakeFeatureLifecycleService(config);
const transactionalFeatureLifecycleService = db
? withTransactional(createFeatureLifecycleService(config), db)
: withFakeTransactional(
createFakeFeatureLifecycleService(config).featureLifecycleService,
);
const featureLifecycleService = transactionalFeatureLifecycleService;
featureLifecycleService.listen();

return {
Expand Down Expand Up @@ -426,6 +429,7 @@ export const createServices = (
projectInsightsService,
jobService,
featureLifecycleService,
transactionalFeatureLifecycleService,
};
};

Expand Down
1 change: 1 addition & 0 deletions src/lib/types/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,5 @@ export interface IUnleashServices {
projectInsightsService: ProjectInsightsService;
jobService: JobService;
featureLifecycleService: FeatureLifecycleService;
transactionalFeatureLifecycleService: WithTransactional<FeatureLifecycleService>;
}

0 comments on commit d29230c

Please sign in to comment.