1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-21 13:47:39 +02:00

feat: transactional bulk update (#3806)

This commit is contained in:
Mateusz Kwasniewski 2023-05-19 08:44:17 +02:00 committed by GitHub
parent 4adc977ba0
commit f9409fc0e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 21 deletions

View File

@ -107,7 +107,7 @@ class AdminApi extends Controller {
'/feedback',
new UserFeedbackController(config, services).router,
);
this.app.use('/projects', new ProjectApi(config, services).router);
this.app.use('/projects', new ProjectApi(config, services, db).router);
this.app.use(
'/environments',
new EnvironmentsController(config, services).router,

View File

@ -24,6 +24,8 @@ import { OpenApiService, SettingService } from '../../../services';
import { IAuthRequest } from '../../unleash-types';
import { ProjectApiTokenController } from './api-token';
import ProjectArchiveController from './project-archive';
import { createKnexTransactionStarter } from '../../../db/transaction';
import { Db } from '../../../db/db';
export default class ProjectApi extends Controller {
private projectService: ProjectService;
@ -32,7 +34,7 @@ export default class ProjectApi extends Controller {
private openApiService: OpenApiService;
constructor(config: IUnleashConfig, services: IUnleashServices) {
constructor(config: IUnleashConfig, services: IUnleashServices, db: Db) {
super(config);
this.projectService = services.projectService;
this.openApiService = services.openApiService;
@ -70,7 +72,14 @@ export default class ProjectApi extends Controller {
],
});
this.use('/', new ProjectFeaturesController(config, services).router);
this.use(
'/',
new ProjectFeaturesController(
config,
services,
createKnexTransactionStarter(db),
).router,
);
this.use('/', new EnvironmentsController(config, services).router);
this.use('/', new ProjectHealthReport(config, services).router);
this.use('/', new VariantsController(config, services).router);

View File

@ -42,6 +42,10 @@ import {
import { OpenApiService, FeatureToggleService } from '../../../services';
import { querySchema } from '../../../schema/feature-schema';
import { BatchStaleSchema } from '../../../openapi/spec/batch-stale-schema';
import {
TransactionCreator,
UnleashTransaction,
} from '../../../db/transaction';
interface FeatureStrategyParams {
projectId: string;
@ -90,24 +94,41 @@ const PATH_STRATEGY = `${PATH_STRATEGIES}/:strategyId`;
type ProjectFeaturesServices = Pick<
IUnleashServices,
'featureToggleServiceV2' | 'projectHealthService' | 'openApiService'
| 'featureToggleServiceV2'
| 'projectHealthService'
| 'openApiService'
| 'transactionalFeatureToggleService'
>;
export default class ProjectFeaturesController extends Controller {
private featureService: FeatureToggleService;
private transactionalFeatureToggleService: (
db: UnleashTransaction,
) => FeatureToggleService;
private openApiService: OpenApiService;
private flagResolver: IFlagResolver;
private readonly logger: Logger;
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
constructor(
config: IUnleashConfig,
{ featureToggleServiceV2, openApiService }: ProjectFeaturesServices,
{
featureToggleServiceV2,
openApiService,
transactionalFeatureToggleService,
}: ProjectFeaturesServices,
startTransaction: TransactionCreator<UnleashTransaction>,
) {
super(config);
this.featureService = featureToggleServiceV2;
this.transactionalFeatureToggleService =
transactionalFeatureToggleService;
this.startTransaction = startTransaction;
this.openApiService = openApiService;
this.flagResolver = config.flagResolver;
this.logger = config.getLogger('/admin-api/project/features.ts');
@ -727,14 +748,16 @@ export default class ProjectFeaturesController extends Controller {
const { shouldActivateDisabledStrategies } = req.query;
const { features } = req.body;
await this.featureService.bulkUpdateEnabled(
projectId,
features,
environment,
true,
extractUsername(req),
req.user,
shouldActivateDisabledStrategies === 'true',
await this.startTransaction(async (tx) =>
this.transactionalFeatureToggleService(tx).bulkUpdateEnabled(
projectId,
features,
environment,
true,
extractUsername(req),
req.user,
shouldActivateDisabledStrategies === 'true',
),
);
res.status(200).end();
}
@ -752,14 +775,16 @@ export default class ProjectFeaturesController extends Controller {
const { shouldActivateDisabledStrategies } = req.query;
const { features } = req.body;
await this.featureService.bulkUpdateEnabled(
projectId,
features,
environment,
false,
extractUsername(req),
req.user,
shouldActivateDisabledStrategies === 'true',
await this.startTransaction(async (tx) =>
this.transactionalFeatureToggleService(tx).bulkUpdateEnabled(
projectId,
features,
environment,
false,
extractUsername(req),
req.user,
shouldActivateDisabledStrategies === 'true',
),
);
res.status(200).end();
}

View File

@ -57,6 +57,7 @@ import {
createFakeChangeRequestAccessService,
} from '../features/change-request-access-service/createChangeRequestAccessReadModel';
import ConfigurationRevisionService from '../features/feature-toggle/configuration-revision-service';
import { createFeatureToggleService } from '../features';
// TODO: will be moved to scheduler feature directory
export const scheduleServices = (services: IUnleashServices): void => {
@ -184,6 +185,8 @@ export const createServices = (
: createFakeExportImportTogglesService(config);
const transactionalExportImportService = (txDb: Knex.Transaction) =>
createExportImportTogglesService(txDb, config);
const transactionalFeatureToggleService = (txDb: Knex.Transaction) =>
createFeatureToggleService(txDb, config);
const userSplashService = new UserSplashService(stores, config);
const openApiService = new OpenApiService(config);
const clientSpecService = new ClientSpecService(config);
@ -275,6 +278,7 @@ export const createServices = (
transactionalExportImportService,
schedulerService,
configurationRevisionService,
transactionalFeatureToggleService,
};
};

View File

@ -91,4 +91,7 @@ export interface IUnleashServices {
transactionalExportImportService: (
db: Knex.Transaction,
) => ExportImportService;
transactionalFeatureToggleService: (
db: Knex.Transaction,
) => FeatureToggleService;
}