mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
chore: revamp transactional impl (#4916)
## About the changes This transactional implementation decorates a service with a transactional method that removes the need to start transactions in the method using the service. This is a gradual rollout with a feature toggle, just because transactions are not easy.
This commit is contained in:
parent
630028acba
commit
0da48cc0d1
@ -105,6 +105,7 @@ exports[`should create default config 1`] = `
|
|||||||
"proPlanAutoCharge": false,
|
"proPlanAutoCharge": false,
|
||||||
"responseTimeWithAppNameKillSwitch": false,
|
"responseTimeWithAppNameKillSwitch": false,
|
||||||
"strictSchemaValidation": false,
|
"strictSchemaValidation": false,
|
||||||
|
"transactionalDecorator": false,
|
||||||
"variantTypeNumber": false,
|
"variantTypeNumber": false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -144,6 +145,7 @@ exports[`should create default config 1`] = `
|
|||||||
"proPlanAutoCharge": false,
|
"proPlanAutoCharge": false,
|
||||||
"responseTimeWithAppNameKillSwitch": false,
|
"responseTimeWithAppNameKillSwitch": false,
|
||||||
"strictSchemaValidation": false,
|
"strictSchemaValidation": false,
|
||||||
|
"transactionalDecorator": false,
|
||||||
"variantTypeNumber": false,
|
"variantTypeNumber": false,
|
||||||
},
|
},
|
||||||
"externalResolver": {
|
"externalResolver": {
|
||||||
|
@ -20,3 +20,34 @@ export const createKnexTransactionStarter = (
|
|||||||
}
|
}
|
||||||
return transaction;
|
return transaction;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DbServiceFactory<S> = (db: Knex) => S;
|
||||||
|
export type WithTransactional<S> = S & {
|
||||||
|
transactional: <R>(fn: (service: S) => R) => Promise<R>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function withTransactional<S>(
|
||||||
|
serviceFactory: (db: Knex) => S,
|
||||||
|
db: Knex,
|
||||||
|
): WithTransactional<S> {
|
||||||
|
const service = serviceFactory(db) as WithTransactional<S>;
|
||||||
|
|
||||||
|
service.transactional = async <R>(fn: (service: S) => R) =>
|
||||||
|
db.transaction(async (trx: Knex.Transaction) => {
|
||||||
|
const transactionalService = serviceFactory(trx);
|
||||||
|
return fn(transactionalService);
|
||||||
|
});
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Just for testing purposes */
|
||||||
|
export function withFakeTransactional<S>(service: S): WithTransactional<S> {
|
||||||
|
const serviceWithFakeTransactional = service as WithTransactional<S>;
|
||||||
|
|
||||||
|
serviceWithFakeTransactional.transactional = async <R>(
|
||||||
|
fn: (service: S) => R,
|
||||||
|
) => fn(serviceWithFakeTransactional);
|
||||||
|
|
||||||
|
return serviceWithFakeTransactional;
|
||||||
|
}
|
||||||
|
@ -43,6 +43,7 @@ import {
|
|||||||
createFakePrivateProjectChecker,
|
createFakePrivateProjectChecker,
|
||||||
createPrivateProjectChecker,
|
createPrivateProjectChecker,
|
||||||
} from '../private-project/createPrivateProjectChecker';
|
} from '../private-project/createPrivateProjectChecker';
|
||||||
|
import { DbServiceFactory } from 'lib/db/transaction';
|
||||||
|
|
||||||
export const createFakeExportImportTogglesService = (
|
export const createFakeExportImportTogglesService = (
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
@ -127,109 +128,121 @@ export const createFakeExportImportTogglesService = (
|
|||||||
return exportImportService;
|
return exportImportService;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deferredExportImportTogglesService = (
|
||||||
|
config: IUnleashConfig,
|
||||||
|
): DbServiceFactory<ExportImportService> => {
|
||||||
|
return (db: Db) => {
|
||||||
|
const { eventBus, getLogger, flagResolver } = config;
|
||||||
|
const importTogglesStore = new ImportTogglesStore(db);
|
||||||
|
const featureToggleStore = new FeatureToggleStore(
|
||||||
|
db,
|
||||||
|
eventBus,
|
||||||
|
getLogger,
|
||||||
|
);
|
||||||
|
const tagStore = new TagStore(db, eventBus, getLogger);
|
||||||
|
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
|
||||||
|
const segmentStore = new SegmentStore(
|
||||||
|
db,
|
||||||
|
eventBus,
|
||||||
|
getLogger,
|
||||||
|
flagResolver,
|
||||||
|
);
|
||||||
|
const projectStore = new ProjectStore(
|
||||||
|
db,
|
||||||
|
eventBus,
|
||||||
|
getLogger,
|
||||||
|
flagResolver,
|
||||||
|
);
|
||||||
|
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
|
||||||
|
const strategyStore = new StrategyStore(db, getLogger);
|
||||||
|
const contextFieldStore = new ContextFieldStore(
|
||||||
|
db,
|
||||||
|
getLogger,
|
||||||
|
flagResolver,
|
||||||
|
);
|
||||||
|
const featureStrategiesStore = new FeatureStrategiesStore(
|
||||||
|
db,
|
||||||
|
eventBus,
|
||||||
|
getLogger,
|
||||||
|
flagResolver,
|
||||||
|
);
|
||||||
|
const featureEnvironmentStore = new FeatureEnvironmentStore(
|
||||||
|
db,
|
||||||
|
eventBus,
|
||||||
|
getLogger,
|
||||||
|
);
|
||||||
|
const eventStore = new EventStore(db, getLogger);
|
||||||
|
const accessService = createAccessService(db, config);
|
||||||
|
const featureToggleService = createFeatureToggleService(db, config);
|
||||||
|
const privateProjectChecker = createPrivateProjectChecker(db, config);
|
||||||
|
|
||||||
|
const eventService = new EventService(
|
||||||
|
{
|
||||||
|
eventStore,
|
||||||
|
featureTagStore,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
|
||||||
|
const featureTagService = new FeatureTagService(
|
||||||
|
{
|
||||||
|
tagStore,
|
||||||
|
featureTagStore,
|
||||||
|
featureToggleStore,
|
||||||
|
},
|
||||||
|
{ getLogger },
|
||||||
|
eventService,
|
||||||
|
);
|
||||||
|
const contextService = new ContextService(
|
||||||
|
{
|
||||||
|
projectStore,
|
||||||
|
contextFieldStore,
|
||||||
|
featureStrategiesStore,
|
||||||
|
},
|
||||||
|
{ getLogger, flagResolver },
|
||||||
|
eventService,
|
||||||
|
privateProjectChecker,
|
||||||
|
);
|
||||||
|
const strategyService = new StrategyService(
|
||||||
|
{ strategyStore },
|
||||||
|
{ getLogger },
|
||||||
|
eventService,
|
||||||
|
);
|
||||||
|
const tagTypeService = new TagTypeService(
|
||||||
|
{ tagTypeStore },
|
||||||
|
{ getLogger },
|
||||||
|
eventService,
|
||||||
|
);
|
||||||
|
const exportImportService = new ExportImportService(
|
||||||
|
{
|
||||||
|
importTogglesStore,
|
||||||
|
featureStrategiesStore,
|
||||||
|
contextFieldStore,
|
||||||
|
featureToggleStore,
|
||||||
|
featureTagStore,
|
||||||
|
segmentStore,
|
||||||
|
tagTypeStore,
|
||||||
|
featureEnvironmentStore,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
{
|
||||||
|
featureToggleService,
|
||||||
|
featureTagService,
|
||||||
|
accessService,
|
||||||
|
eventService,
|
||||||
|
contextService,
|
||||||
|
strategyService,
|
||||||
|
tagTypeService,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return exportImportService;
|
||||||
|
};
|
||||||
|
};
|
||||||
export const createExportImportTogglesService = (
|
export const createExportImportTogglesService = (
|
||||||
db: Db,
|
db: Db,
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
): ExportImportService => {
|
): ExportImportService => {
|
||||||
const { eventBus, getLogger, flagResolver } = config;
|
const unboundService = deferredExportImportTogglesService(config);
|
||||||
const importTogglesStore = new ImportTogglesStore(db);
|
return unboundService(db);
|
||||||
const featureToggleStore = new FeatureToggleStore(db, eventBus, getLogger);
|
|
||||||
const tagStore = new TagStore(db, eventBus, getLogger);
|
|
||||||
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
|
|
||||||
const segmentStore = new SegmentStore(
|
|
||||||
db,
|
|
||||||
eventBus,
|
|
||||||
getLogger,
|
|
||||||
flagResolver,
|
|
||||||
);
|
|
||||||
const projectStore = new ProjectStore(
|
|
||||||
db,
|
|
||||||
eventBus,
|
|
||||||
getLogger,
|
|
||||||
flagResolver,
|
|
||||||
);
|
|
||||||
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
|
|
||||||
const strategyStore = new StrategyStore(db, getLogger);
|
|
||||||
const contextFieldStore = new ContextFieldStore(
|
|
||||||
db,
|
|
||||||
getLogger,
|
|
||||||
flagResolver,
|
|
||||||
);
|
|
||||||
const featureStrategiesStore = new FeatureStrategiesStore(
|
|
||||||
db,
|
|
||||||
eventBus,
|
|
||||||
getLogger,
|
|
||||||
flagResolver,
|
|
||||||
);
|
|
||||||
const featureEnvironmentStore = new FeatureEnvironmentStore(
|
|
||||||
db,
|
|
||||||
eventBus,
|
|
||||||
getLogger,
|
|
||||||
);
|
|
||||||
const eventStore = new EventStore(db, getLogger);
|
|
||||||
const accessService = createAccessService(db, config);
|
|
||||||
const featureToggleService = createFeatureToggleService(db, config);
|
|
||||||
const privateProjectChecker = createPrivateProjectChecker(db, config);
|
|
||||||
|
|
||||||
const eventService = new EventService(
|
|
||||||
{
|
|
||||||
eventStore,
|
|
||||||
featureTagStore,
|
|
||||||
},
|
|
||||||
config,
|
|
||||||
);
|
|
||||||
|
|
||||||
const featureTagService = new FeatureTagService(
|
|
||||||
{
|
|
||||||
tagStore,
|
|
||||||
featureTagStore,
|
|
||||||
featureToggleStore,
|
|
||||||
},
|
|
||||||
{ getLogger },
|
|
||||||
eventService,
|
|
||||||
);
|
|
||||||
const contextService = new ContextService(
|
|
||||||
{
|
|
||||||
projectStore,
|
|
||||||
contextFieldStore,
|
|
||||||
featureStrategiesStore,
|
|
||||||
},
|
|
||||||
{ getLogger, flagResolver },
|
|
||||||
eventService,
|
|
||||||
privateProjectChecker,
|
|
||||||
);
|
|
||||||
const strategyService = new StrategyService(
|
|
||||||
{ strategyStore },
|
|
||||||
{ getLogger },
|
|
||||||
eventService,
|
|
||||||
);
|
|
||||||
const tagTypeService = new TagTypeService(
|
|
||||||
{ tagTypeStore },
|
|
||||||
{ getLogger },
|
|
||||||
eventService,
|
|
||||||
);
|
|
||||||
const exportImportService = new ExportImportService(
|
|
||||||
{
|
|
||||||
importTogglesStore,
|
|
||||||
featureStrategiesStore,
|
|
||||||
contextFieldStore,
|
|
||||||
featureToggleStore,
|
|
||||||
featureTagStore,
|
|
||||||
segmentStore,
|
|
||||||
tagTypeStore,
|
|
||||||
featureEnvironmentStore,
|
|
||||||
},
|
|
||||||
config,
|
|
||||||
{
|
|
||||||
featureToggleService,
|
|
||||||
featureTagService,
|
|
||||||
accessService,
|
|
||||||
eventService,
|
|
||||||
contextService,
|
|
||||||
strategyService,
|
|
||||||
tagTypeService,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return exportImportService;
|
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,11 @@ import Controller from '../../routes/controller';
|
|||||||
import { Logger } from '../../logger';
|
import { Logger } from '../../logger';
|
||||||
import ExportImportService from './export-import-service';
|
import ExportImportService from './export-import-service';
|
||||||
import { OpenApiService } from '../../services';
|
import { OpenApiService } from '../../services';
|
||||||
import { TransactionCreator, UnleashTransaction } from '../../db/transaction';
|
import {
|
||||||
|
TransactionCreator,
|
||||||
|
UnleashTransaction,
|
||||||
|
WithTransactional,
|
||||||
|
} from '../../db/transaction';
|
||||||
import {
|
import {
|
||||||
IUnleashConfig,
|
IUnleashConfig,
|
||||||
IUnleashServices,
|
IUnleashServices,
|
||||||
@ -28,14 +32,19 @@ import ApiUser from '../../types/api-user';
|
|||||||
class ExportImportController extends Controller {
|
class ExportImportController extends Controller {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
|
/** @deprecated gradually rolling out exportImportV2 */
|
||||||
private exportImportService: ExportImportService;
|
private exportImportService: ExportImportService;
|
||||||
|
|
||||||
|
/** @deprecated gradually rolling out exportImportV2 */
|
||||||
private transactionalExportImportService: (
|
private transactionalExportImportService: (
|
||||||
db: UnleashTransaction,
|
db: UnleashTransaction,
|
||||||
) => ExportImportService;
|
) => ExportImportService;
|
||||||
|
|
||||||
|
private exportImportServiceV2: WithTransactional<ExportImportService>;
|
||||||
|
|
||||||
private openApiService: OpenApiService;
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
|
/** @deprecated gradually rolling out exportImportV2 */
|
||||||
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -43,10 +52,12 @@ class ExportImportController extends Controller {
|
|||||||
{
|
{
|
||||||
exportImportService,
|
exportImportService,
|
||||||
transactionalExportImportService,
|
transactionalExportImportService,
|
||||||
|
exportImportServiceV2,
|
||||||
openApiService,
|
openApiService,
|
||||||
}: Pick<
|
}: Pick<
|
||||||
IUnleashServices,
|
IUnleashServices,
|
||||||
| 'exportImportService'
|
| 'exportImportService'
|
||||||
|
| 'exportImportServiceV2'
|
||||||
| 'openApiService'
|
| 'openApiService'
|
||||||
| 'transactionalExportImportService'
|
| 'transactionalExportImportService'
|
||||||
>,
|
>,
|
||||||
@ -57,6 +68,7 @@ class ExportImportController extends Controller {
|
|||||||
this.exportImportService = exportImportService;
|
this.exportImportService = exportImportService;
|
||||||
this.transactionalExportImportService =
|
this.transactionalExportImportService =
|
||||||
transactionalExportImportService;
|
transactionalExportImportService;
|
||||||
|
this.exportImportServiceV2 = exportImportServiceV2;
|
||||||
this.startTransaction = startTransaction;
|
this.startTransaction = startTransaction;
|
||||||
this.openApiService = openApiService;
|
this.openApiService = openApiService;
|
||||||
this.route({
|
this.route({
|
||||||
@ -128,7 +140,13 @@ class ExportImportController extends Controller {
|
|||||||
this.verifyExportImportEnabled();
|
this.verifyExportImportEnabled();
|
||||||
const query = req.body;
|
const query = req.body;
|
||||||
const userName = extractUsername(req);
|
const userName = extractUsername(req);
|
||||||
const data = await this.exportImportService.export(query, userName);
|
|
||||||
|
const useTransactionalDecorator = this.config.flagResolver.isEnabled(
|
||||||
|
'transactionalDecorator',
|
||||||
|
);
|
||||||
|
const data = useTransactionalDecorator
|
||||||
|
? await this.exportImportServiceV2.export(query, userName)
|
||||||
|
: await this.exportImportService.export(query, userName);
|
||||||
|
|
||||||
this.openApiService.respondWithValidation(
|
this.openApiService.respondWithValidation(
|
||||||
200,
|
200,
|
||||||
@ -145,9 +163,17 @@ class ExportImportController extends Controller {
|
|||||||
this.verifyExportImportEnabled();
|
this.verifyExportImportEnabled();
|
||||||
const dto = req.body;
|
const dto = req.body;
|
||||||
const { user } = req;
|
const { user } = req;
|
||||||
const validation = await this.startTransaction(async (tx) =>
|
|
||||||
this.transactionalExportImportService(tx).validate(dto, user),
|
const useTransactionalDecorator = this.config.flagResolver.isEnabled(
|
||||||
|
'transactionalDecorator',
|
||||||
);
|
);
|
||||||
|
const validation = useTransactionalDecorator
|
||||||
|
? await this.exportImportServiceV2.transactional((service) =>
|
||||||
|
service.validate(dto, user),
|
||||||
|
)
|
||||||
|
: await this.startTransaction(async (tx) =>
|
||||||
|
this.transactionalExportImportService(tx).validate(dto, user),
|
||||||
|
);
|
||||||
|
|
||||||
this.openApiService.respondWithValidation(
|
this.openApiService.respondWithValidation(
|
||||||
200,
|
200,
|
||||||
@ -172,10 +198,20 @@ class ExportImportController extends Controller {
|
|||||||
|
|
||||||
const dto = req.body;
|
const dto = req.body;
|
||||||
|
|
||||||
await this.startTransaction(async (tx) =>
|
const useTransactionalDecorator = this.config.flagResolver.isEnabled(
|
||||||
this.transactionalExportImportService(tx).import(dto, user),
|
'transactionalDecorator',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (useTransactionalDecorator) {
|
||||||
|
await this.exportImportServiceV2.transactional((service) =>
|
||||||
|
service.import(dto, user),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await this.startTransaction(async (tx) =>
|
||||||
|
this.transactionalExportImportService(tx).import(dto, user),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,10 @@ import { Knex } from 'knex';
|
|||||||
import {
|
import {
|
||||||
createExportImportTogglesService,
|
createExportImportTogglesService,
|
||||||
createFakeExportImportTogglesService,
|
createFakeExportImportTogglesService,
|
||||||
|
deferredExportImportTogglesService,
|
||||||
} from '../features/export-import-toggles/createExportImportService';
|
} from '../features/export-import-toggles/createExportImportService';
|
||||||
import { Db } from '../db/db';
|
import { Db } from '../db/db';
|
||||||
|
import { withFakeTransactional, withTransactional } from '../db/transaction';
|
||||||
import {
|
import {
|
||||||
createChangeRequestAccessReadModel,
|
createChangeRequestAccessReadModel,
|
||||||
createFakeChangeRequestAccessService,
|
createFakeChangeRequestAccessService,
|
||||||
@ -274,10 +276,12 @@ export const createServices = (
|
|||||||
projectService,
|
projectService,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: this is a temporary seam to enable packaging by feature
|
|
||||||
const exportImportService = db
|
const exportImportService = db
|
||||||
? createExportImportTogglesService(db, config)
|
? createExportImportTogglesService(db, config)
|
||||||
: createFakeExportImportTogglesService(config);
|
: createFakeExportImportTogglesService(config);
|
||||||
|
const exportImportServiceV2 = db
|
||||||
|
? withTransactional(deferredExportImportTogglesService(config), db)
|
||||||
|
: withFakeTransactional(createFakeExportImportTogglesService(config));
|
||||||
const transactionalExportImportService = (txDb: Knex.Transaction) =>
|
const transactionalExportImportService = (txDb: Knex.Transaction) =>
|
||||||
createExportImportTogglesService(txDb, config);
|
createExportImportTogglesService(txDb, config);
|
||||||
const transactionalFeatureToggleService = (txDb: Knex.Transaction) =>
|
const transactionalFeatureToggleService = (txDb: Knex.Transaction) =>
|
||||||
@ -380,6 +384,7 @@ export const createServices = (
|
|||||||
maintenanceService,
|
maintenanceService,
|
||||||
exportImportService,
|
exportImportService,
|
||||||
transactionalExportImportService,
|
transactionalExportImportService,
|
||||||
|
exportImportServiceV2,
|
||||||
schedulerService,
|
schedulerService,
|
||||||
configurationRevisionService,
|
configurationRevisionService,
|
||||||
transactionalFeatureToggleService,
|
transactionalFeatureToggleService,
|
||||||
|
@ -31,7 +31,8 @@ export type IFlagKey =
|
|||||||
| 'privateProjects'
|
| 'privateProjects'
|
||||||
| 'dependentFeatures'
|
| 'dependentFeatures'
|
||||||
| 'datadogJsonTemplate'
|
| 'datadogJsonTemplate'
|
||||||
| 'disableMetrics';
|
| 'disableMetrics'
|
||||||
|
| 'transactionalDecorator';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -147,6 +148,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS,
|
process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
transactionalDecorator: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_TRANSACTIONAL_DECORATOR,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -45,6 +45,7 @@ import ConfigurationRevisionService from '../features/feature-toggle/configurati
|
|||||||
import EventAnnouncerService from 'lib/services/event-announcer-service';
|
import EventAnnouncerService from 'lib/services/event-announcer-service';
|
||||||
import { IPrivateProjectChecker } from '../features/private-project/privateProjectCheckerType';
|
import { IPrivateProjectChecker } from '../features/private-project/privateProjectCheckerType';
|
||||||
import { DependentFeaturesService } from '../features/dependent-features/dependent-features-service';
|
import { DependentFeaturesService } from '../features/dependent-features/dependent-features-service';
|
||||||
|
import { WithTransactional } from 'lib/db/transaction';
|
||||||
|
|
||||||
export interface IUnleashServices {
|
export interface IUnleashServices {
|
||||||
accessService: AccessService;
|
accessService: AccessService;
|
||||||
@ -88,10 +89,13 @@ export interface IUnleashServices {
|
|||||||
instanceStatsService: InstanceStatsService;
|
instanceStatsService: InstanceStatsService;
|
||||||
favoritesService: FavoritesService;
|
favoritesService: FavoritesService;
|
||||||
maintenanceService: MaintenanceService;
|
maintenanceService: MaintenanceService;
|
||||||
|
/** @deprecated prefer exportImportServiceV2, we're doing a gradual rollout */
|
||||||
exportImportService: ExportImportService;
|
exportImportService: ExportImportService;
|
||||||
|
exportImportServiceV2: WithTransactional<ExportImportService>;
|
||||||
configurationRevisionService: ConfigurationRevisionService;
|
configurationRevisionService: ConfigurationRevisionService;
|
||||||
schedulerService: SchedulerService;
|
schedulerService: SchedulerService;
|
||||||
eventAnnouncerService: EventAnnouncerService;
|
eventAnnouncerService: EventAnnouncerService;
|
||||||
|
/** @deprecated prefer exportImportServiceV2, we're doing a gradual rollout */
|
||||||
transactionalExportImportService: (
|
transactionalExportImportService: (
|
||||||
db: Knex.Transaction,
|
db: Knex.Transaction,
|
||||||
) => ExportImportService;
|
) => ExportImportService;
|
||||||
|
@ -45,6 +45,7 @@ process.nextTick(async () => {
|
|||||||
accessOverview: true,
|
accessOverview: true,
|
||||||
datadogJsonTemplate: true,
|
datadogJsonTemplate: true,
|
||||||
dependentFeatures: true,
|
dependentFeatures: true,
|
||||||
|
transactionalDecorator: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user