mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: dependent features use new transaction mechanism (#5073)
This commit is contained in:
parent
4dd01c1765
commit
75b131162e
@ -17,35 +17,33 @@ import {
|
||||
import { FeaturesReadModel } from '../feature-toggle/features-read-model';
|
||||
import { FakeFeaturesReadModel } from '../feature-toggle/fakes/fake-features-read-model';
|
||||
|
||||
export const createDependentFeaturesService = (
|
||||
db: Db,
|
||||
config: IUnleashConfig,
|
||||
): DependentFeaturesService => {
|
||||
const { getLogger, eventBus } = config;
|
||||
const eventStore = new EventStore(db, getLogger);
|
||||
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
|
||||
const eventService = new EventService(
|
||||
{
|
||||
eventStore,
|
||||
featureTagStore,
|
||||
},
|
||||
config,
|
||||
);
|
||||
const dependentFeaturesStore = new DependentFeaturesStore(db);
|
||||
const dependentFeaturesReadModel = new DependentFeaturesReadModel(db);
|
||||
const changeRequestAccessReadModel = createChangeRequestAccessReadModel(
|
||||
db,
|
||||
config,
|
||||
);
|
||||
const featuresReadModel = new FeaturesReadModel(db);
|
||||
return new DependentFeaturesService({
|
||||
dependentFeaturesStore,
|
||||
dependentFeaturesReadModel,
|
||||
changeRequestAccessReadModel,
|
||||
featuresReadModel,
|
||||
eventService,
|
||||
});
|
||||
};
|
||||
export const createDependentFeaturesService =
|
||||
(config: IUnleashConfig) => (db: Db): DependentFeaturesService => {
|
||||
const { getLogger, eventBus } = config;
|
||||
const eventStore = new EventStore(db, getLogger);
|
||||
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
|
||||
const eventService = new EventService(
|
||||
{
|
||||
eventStore,
|
||||
featureTagStore,
|
||||
},
|
||||
config,
|
||||
);
|
||||
const dependentFeaturesStore = new DependentFeaturesStore(db);
|
||||
const dependentFeaturesReadModel = new DependentFeaturesReadModel(db);
|
||||
const changeRequestAccessReadModel = createChangeRequestAccessReadModel(
|
||||
db,
|
||||
config,
|
||||
);
|
||||
const featuresReadModel = new FeaturesReadModel(db);
|
||||
return new DependentFeaturesService({
|
||||
dependentFeaturesStore,
|
||||
dependentFeaturesReadModel,
|
||||
changeRequestAccessReadModel,
|
||||
featuresReadModel,
|
||||
eventService,
|
||||
});
|
||||
};
|
||||
|
||||
export const createFakeDependentFeaturesService = (
|
||||
config: IUnleashConfig,
|
||||
|
@ -20,7 +20,11 @@ import {
|
||||
import { IAuthRequest } from '../../routes/unleash-types';
|
||||
import { InvalidOperationError } from '../../error';
|
||||
import { DependentFeaturesService } from './dependent-features-service';
|
||||
import { TransactionCreator, UnleashTransaction } from '../../db/transaction';
|
||||
import {
|
||||
TransactionCreator,
|
||||
UnleashTransaction,
|
||||
WithTransactional,
|
||||
} from '../../db/transaction';
|
||||
|
||||
interface ProjectParams {
|
||||
projectId: string;
|
||||
@ -44,19 +48,11 @@ const PATH_DEPENDENCY = `${PATH_FEATURE}/dependencies/:parent`;
|
||||
|
||||
type DependentFeaturesServices = Pick<
|
||||
IUnleashServices,
|
||||
| 'transactionalDependentFeaturesService'
|
||||
| 'dependentFeaturesService'
|
||||
| 'openApiService'
|
||||
'transactionalDependentFeaturesService' | 'openApiService'
|
||||
>;
|
||||
|
||||
export default class DependentFeaturesController extends Controller {
|
||||
private transactionalDependentFeaturesService: (
|
||||
db: UnleashTransaction,
|
||||
) => DependentFeaturesService;
|
||||
|
||||
private dependentFeaturesService: DependentFeaturesService;
|
||||
|
||||
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
||||
private dependentFeaturesService: WithTransactional<DependentFeaturesService>;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
@ -68,18 +64,13 @@ export default class DependentFeaturesController extends Controller {
|
||||
config: IUnleashConfig,
|
||||
{
|
||||
transactionalDependentFeaturesService,
|
||||
dependentFeaturesService,
|
||||
openApiService,
|
||||
}: DependentFeaturesServices,
|
||||
startTransaction: TransactionCreator<UnleashTransaction>,
|
||||
) {
|
||||
super(config);
|
||||
this.transactionalDependentFeaturesService =
|
||||
transactionalDependentFeaturesService;
|
||||
this.dependentFeaturesService = dependentFeaturesService;
|
||||
this.dependentFeaturesService = transactionalDependentFeaturesService;
|
||||
this.openApiService = openApiService;
|
||||
this.flagResolver = config.flagResolver;
|
||||
this.startTransaction = startTransaction;
|
||||
this.logger = config.getLogger(
|
||||
'/dependent-features/dependent-feature-service.ts',
|
||||
);
|
||||
@ -196,10 +187,8 @@ export default class DependentFeaturesController extends Controller {
|
||||
const { variants, enabled, feature } = req.body;
|
||||
|
||||
if (this.config.flagResolver.isEnabled('dependentFeatures')) {
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalDependentFeaturesService(
|
||||
tx,
|
||||
).upsertFeatureDependency(
|
||||
await this.dependentFeaturesService.transactional((service) =>
|
||||
service.upsertFeatureDependency(
|
||||
{ child, projectId },
|
||||
{
|
||||
variants,
|
||||
@ -209,6 +198,7 @@ export default class DependentFeaturesController extends Controller {
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
|
||||
res.status(200).end();
|
||||
} else {
|
||||
throw new InvalidOperationError(
|
||||
@ -224,13 +214,15 @@ export default class DependentFeaturesController extends Controller {
|
||||
const { child, parent, projectId } = req.params;
|
||||
|
||||
if (this.config.flagResolver.isEnabled('dependentFeatures')) {
|
||||
await this.dependentFeaturesService.deleteFeatureDependency(
|
||||
{
|
||||
parent,
|
||||
child,
|
||||
},
|
||||
projectId,
|
||||
req.user,
|
||||
await this.dependentFeaturesService.transactional((service) =>
|
||||
service.deleteFeatureDependency(
|
||||
{
|
||||
parent,
|
||||
child,
|
||||
},
|
||||
projectId,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
res.status(200).end();
|
||||
} else {
|
||||
@ -247,10 +239,12 @@ export default class DependentFeaturesController extends Controller {
|
||||
const { child, projectId } = req.params;
|
||||
|
||||
if (this.config.flagResolver.isEnabled('dependentFeatures')) {
|
||||
await this.dependentFeaturesService.deleteFeaturesDependencies(
|
||||
[child],
|
||||
projectId,
|
||||
req.user,
|
||||
await this.dependentFeaturesService.transactional((service) =>
|
||||
service.deleteFeaturesDependencies(
|
||||
[child],
|
||||
projectId,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
res.status(200).end();
|
||||
} else {
|
||||
|
@ -236,10 +236,8 @@ export const deferredExportImportTogglesService = (
|
||||
|
||||
const segmentService = createSegmentService(db, config);
|
||||
|
||||
const dependentFeaturesService = createDependentFeaturesService(
|
||||
db,
|
||||
config,
|
||||
);
|
||||
const dependentFeaturesService =
|
||||
createDependentFeaturesService(config)(db);
|
||||
|
||||
const exportImportService = new ExportImportService(
|
||||
{
|
||||
|
@ -2,30 +2,29 @@ import { Logger } from '../../logger';
|
||||
import { IStrategy } from '../../types/stores/strategy-store';
|
||||
import { IFeatureToggleStore } from '../feature-toggle/types/feature-toggle-store-type';
|
||||
import { IFeatureStrategiesStore } from '../feature-toggle/types/feature-toggle-strategies-store-type';
|
||||
import {
|
||||
IUnleashConfig,
|
||||
IContextFieldStore,
|
||||
IUnleashStores,
|
||||
ISegmentStore,
|
||||
IFeatureEnvironmentStore,
|
||||
ITagTypeStore,
|
||||
IFeatureTagStore,
|
||||
FeatureToggleDTO,
|
||||
IFeatureStrategy,
|
||||
IFeatureStrategySegment,
|
||||
IVariant,
|
||||
} from '../../types';
|
||||
import { ExportQuerySchema, ImportTogglesSchema } from '../../openapi';
|
||||
import {
|
||||
FEATURES_EXPORTED,
|
||||
FEATURES_IMPORTED,
|
||||
FeatureToggleDTO,
|
||||
IContextFieldStore,
|
||||
IFeatureEnvironmentStore,
|
||||
IFeatureStrategy,
|
||||
IFeatureStrategySegment,
|
||||
IFeatureTagStore,
|
||||
IFlagResolver,
|
||||
ISegmentStore,
|
||||
ITagTypeStore,
|
||||
IUnleashConfig,
|
||||
IUnleashServices,
|
||||
IUnleashStores,
|
||||
IVariant,
|
||||
WithRequired,
|
||||
} from '../../types';
|
||||
import {
|
||||
ExportQuerySchema,
|
||||
ExportResultSchema,
|
||||
FeatureStrategySchema,
|
||||
ImportTogglesSchema,
|
||||
ImportTogglesValidateSchema,
|
||||
} from '../../openapi';
|
||||
import User from '../../types/user';
|
||||
|
@ -119,7 +119,7 @@ export const createFeatureToggleService = (
|
||||
|
||||
const dependentFeaturesReadModel = new DependentFeaturesReadModel(db);
|
||||
|
||||
const dependentFeaturesService = createDependentFeaturesService(db, config);
|
||||
const dependentFeaturesService = createDependentFeaturesService(config)(db);
|
||||
|
||||
const featureToggleService = new FeatureToggleService(
|
||||
{
|
||||
|
@ -113,14 +113,7 @@ export default class ProjectApi extends Controller {
|
||||
createKnexTransactionStarter(db),
|
||||
).router,
|
||||
);
|
||||
this.use(
|
||||
'/',
|
||||
new DependentFeaturesController(
|
||||
config,
|
||||
services,
|
||||
createKnexTransactionStarter(db),
|
||||
).router,
|
||||
);
|
||||
this.use('/', new DependentFeaturesController(config, services).router);
|
||||
this.use('/', new EnvironmentsController(config, services).router);
|
||||
this.use('/', new ProjectHealthReport(config, services).router);
|
||||
this.use('/', new VariantsController(config, services).router);
|
||||
|
@ -267,11 +267,10 @@ export const createServices = (
|
||||
privateProjectChecker,
|
||||
);
|
||||
|
||||
const dependentFeaturesService = db
|
||||
? createDependentFeaturesService(db, config)
|
||||
: createFakeDependentFeaturesService(config);
|
||||
const transactionalDependentFeaturesService = (txDb: Knex.Transaction) =>
|
||||
createDependentFeaturesService(txDb, config);
|
||||
const transactionalDependentFeaturesService = db
|
||||
? withTransactional(createDependentFeaturesService(config), db)
|
||||
: withFakeTransactional(createFakeDependentFeaturesService(config));
|
||||
const dependentFeaturesService = transactionalDependentFeaturesService;
|
||||
|
||||
const featureToggleServiceV2 = new FeatureToggleService(
|
||||
stores,
|
||||
|
@ -105,8 +105,6 @@ export interface IUnleashServices {
|
||||
transactionalGroupService: (db: Knex.Transaction) => GroupService;
|
||||
privateProjectChecker: IPrivateProjectChecker;
|
||||
dependentFeaturesService: DependentFeaturesService;
|
||||
transactionalDependentFeaturesService: (
|
||||
db: Knex.Transaction,
|
||||
) => DependentFeaturesService;
|
||||
transactionalDependentFeaturesService: WithTransactional<DependentFeaturesService>;
|
||||
clientFeatureToggleService: ClientFeatureToggleService;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user