mirror of
https://github.com/Unleash/unleash.git
synced 2025-11-10 01:19:53 +01:00
chore: resource limits service (#10709)
https://linear.app/unleash/issue/2-3927/implement-resource-limits-service Implements a resource limits service. The implementation looks trivial (or even redundant) in OSS, but by implementing a resource limits service we can make this potentially dynamic and overridable.
This commit is contained in:
parent
9d996f14d9
commit
7462465a0b
@ -9,6 +9,7 @@ import {
|
||||
} from '../events/createEventsService.js';
|
||||
import FakeApiTokenStore from '../../../test/fixtures/fake-api-token-store.js';
|
||||
import { ApiTokenStore } from '../../db/api-token-store.js';
|
||||
import { ResourceLimitsService } from '../resource-limits/resource-limits-service.js';
|
||||
|
||||
export const createApiTokenService = (
|
||||
db: Db,
|
||||
@ -23,11 +24,13 @@ export const createApiTokenService = (
|
||||
);
|
||||
const environmentStore = new EnvironmentStore(db, eventBus, config);
|
||||
const eventService = createEventsService(db, config);
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
return new ApiTokenService(
|
||||
{ apiTokenStore, environmentStore },
|
||||
config,
|
||||
eventService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
};
|
||||
|
||||
@ -36,23 +39,27 @@ export const createFakeApiTokenService = (
|
||||
): {
|
||||
apiTokenService: ApiTokenService;
|
||||
eventService: EventService;
|
||||
resourceLimitsService: ResourceLimitsService;
|
||||
apiTokenStore: FakeApiTokenStore;
|
||||
environmentStore: IEnvironmentStore;
|
||||
} => {
|
||||
const apiTokenStore = new FakeApiTokenStore();
|
||||
const environmentStore = new FakeEnvironmentStore();
|
||||
const eventService = createFakeEventsService(config);
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
const apiTokenService = new ApiTokenService(
|
||||
{ apiTokenStore, environmentStore },
|
||||
config,
|
||||
eventService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
|
||||
return {
|
||||
apiTokenService,
|
||||
apiTokenStore,
|
||||
eventService,
|
||||
resourceLimitsService,
|
||||
environmentStore,
|
||||
};
|
||||
};
|
||||
|
||||
@ -65,12 +65,13 @@ import {
|
||||
createFakeFeatureLinkService,
|
||||
createFeatureLinkService,
|
||||
} from '../feature-links/createFeatureLinkService.js';
|
||||
import { ResourceLimitsService } from '../resource-limits/resource-limits-service.js';
|
||||
|
||||
export const createFeatureToggleService = (
|
||||
db: Db,
|
||||
config: IUnleashConfig,
|
||||
): FeatureToggleService => {
|
||||
const { getLogger, eventBus, flagResolver, resourceLimits } = config;
|
||||
const { getLogger, eventBus, flagResolver } = config;
|
||||
const featureStrategiesStore = new FeatureStrategiesStore(
|
||||
db,
|
||||
eventBus,
|
||||
@ -138,6 +139,8 @@ export const createFeatureToggleService = (
|
||||
|
||||
const featureLinkService = createFeatureLinkService(config)(db);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
const featureToggleService = new FeatureToggleService(
|
||||
{
|
||||
featureStrategiesStore,
|
||||
@ -149,7 +152,7 @@ export const createFeatureToggleService = (
|
||||
contextFieldStore,
|
||||
strategyStore,
|
||||
},
|
||||
{ getLogger, flagResolver, eventBus, resourceLimits },
|
||||
{ getLogger, flagResolver, eventBus },
|
||||
{
|
||||
segmentService,
|
||||
accessService,
|
||||
@ -162,13 +165,14 @@ export const createFeatureToggleService = (
|
||||
featureCollaboratorsReadModel,
|
||||
featureLinksReadModel,
|
||||
featureLinkService,
|
||||
resourceLimitsService,
|
||||
},
|
||||
);
|
||||
return featureToggleService;
|
||||
};
|
||||
|
||||
export const createFakeFeatureToggleService = (config: IUnleashConfig) => {
|
||||
const { getLogger, flagResolver, resourceLimits } = config;
|
||||
const { getLogger, flagResolver } = config;
|
||||
const eventStore = new FakeEventStore();
|
||||
const strategyStore = new FakeStrategiesStore();
|
||||
const featureStrategiesStore = new FakeFeatureStrategiesStore();
|
||||
@ -206,6 +210,8 @@ export const createFakeFeatureToggleService = (config: IUnleashConfig) => {
|
||||
const featureLinksReadModel = new FakeFeatureLinksReadModel();
|
||||
const { featureLinkService } = createFakeFeatureLinkService(config);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
const featureToggleService = new FeatureToggleService(
|
||||
{
|
||||
featureStrategiesStore,
|
||||
@ -221,7 +227,6 @@ export const createFakeFeatureToggleService = (config: IUnleashConfig) => {
|
||||
getLogger,
|
||||
flagResolver,
|
||||
eventBus: new EventEmitter(),
|
||||
resourceLimits,
|
||||
},
|
||||
{
|
||||
segmentService,
|
||||
@ -235,6 +240,7 @@ export const createFakeFeatureToggleService = (config: IUnleashConfig) => {
|
||||
featureCollaboratorsReadModel,
|
||||
featureLinksReadModel,
|
||||
featureLinkService,
|
||||
resourceLimitsService,
|
||||
},
|
||||
);
|
||||
return {
|
||||
|
||||
@ -114,9 +114,9 @@ import type { IFeatureLifecycleReadModel } from '../feature-lifecycle/feature-li
|
||||
import { throwExceedsLimitError } from '../../error/exceeds-limit-error.js';
|
||||
import type { Collaborator } from './types/feature-collaborators-read-model-type.js';
|
||||
import { sortStrategies } from '../../util/sortStrategies.js';
|
||||
import type { ResourceLimitsSchema } from '../../openapi/index.js';
|
||||
import type FeatureLinkService from '../feature-links/feature-link-service.js';
|
||||
import type { IFeatureLink } from '../feature-links/feature-links-read-model-type.js';
|
||||
import type { ResourceLimitsService } from '../resource-limits/resource-limits-service.js';
|
||||
interface IFeatureContext {
|
||||
featureName: string;
|
||||
projectId: string;
|
||||
@ -161,7 +161,7 @@ export type Stores = Pick<
|
||||
|
||||
export type Config = Pick<
|
||||
IUnleashConfig,
|
||||
'getLogger' | 'flagResolver' | 'eventBus' | 'resourceLimits'
|
||||
'getLogger' | 'flagResolver' | 'eventBus'
|
||||
>;
|
||||
|
||||
export type ServicesAndReadModels = {
|
||||
@ -176,6 +176,7 @@ export type ServicesAndReadModels = {
|
||||
featureCollaboratorsReadModel: IFeatureCollaboratorsReadModel;
|
||||
featureLinkService: FeatureLinkService;
|
||||
featureLinksReadModel: IFeatureLinksReadModel;
|
||||
resourceLimitsService: ResourceLimitsService;
|
||||
};
|
||||
|
||||
export class FeatureToggleService {
|
||||
@ -223,7 +224,7 @@ export class FeatureToggleService {
|
||||
|
||||
private eventBus: EventEmitter;
|
||||
|
||||
private resourceLimits: ResourceLimitsSchema;
|
||||
private resourceLimitsService: ResourceLimitsService;
|
||||
|
||||
constructor(
|
||||
{
|
||||
@ -236,7 +237,7 @@ export class FeatureToggleService {
|
||||
contextFieldStore,
|
||||
strategyStore,
|
||||
}: Stores,
|
||||
{ getLogger, flagResolver, eventBus, resourceLimits }: Config,
|
||||
{ getLogger, flagResolver, eventBus }: Config,
|
||||
{
|
||||
segmentService,
|
||||
accessService,
|
||||
@ -249,6 +250,7 @@ export class FeatureToggleService {
|
||||
featureCollaboratorsReadModel,
|
||||
featureLinksReadModel,
|
||||
featureLinkService,
|
||||
resourceLimitsService,
|
||||
}: ServicesAndReadModels,
|
||||
) {
|
||||
this.logger = getLogger('services/feature-toggle-service.ts');
|
||||
@ -273,7 +275,7 @@ export class FeatureToggleService {
|
||||
this.featureLinksReadModel = featureLinksReadModel;
|
||||
this.featureLinkService = featureLinkService;
|
||||
this.eventBus = eventBus;
|
||||
this.resourceLimits = resourceLimits;
|
||||
this.resourceLimitsService = resourceLimitsService;
|
||||
}
|
||||
|
||||
async validateFeaturesContext(
|
||||
@ -396,7 +398,8 @@ export class FeatureToggleService {
|
||||
environment: string;
|
||||
featureName: string;
|
||||
}) {
|
||||
const limit = this.resourceLimits.featureEnvironmentStrategies;
|
||||
const { featureEnvironmentStrategies: limit } =
|
||||
await this.resourceLimitsService.getResourceLimits();
|
||||
const existingCount = (
|
||||
await this.featureStrategiesStore.getStrategiesForFeatureEnv(
|
||||
featureEnv.projectId,
|
||||
@ -412,14 +415,14 @@ export class FeatureToggleService {
|
||||
}
|
||||
}
|
||||
|
||||
private validateConstraintsLimit(constraints: {
|
||||
private async validateConstraintsLimit(constraints: {
|
||||
updated: IConstraint[];
|
||||
existing: IConstraint[];
|
||||
}) {
|
||||
const {
|
||||
constraints: constraintsLimit,
|
||||
constraintValues: constraintValuesLimit,
|
||||
} = this.resourceLimits;
|
||||
} = await this.resourceLimitsService.getResourceLimits();
|
||||
|
||||
if (
|
||||
constraints.updated.length > constraintsLimit &&
|
||||
@ -711,7 +714,7 @@ export class FeatureToggleService {
|
||||
const { name, title, disabled, sortOrder } = strategyConfig;
|
||||
let { constraints, parameters, variants } = strategyConfig;
|
||||
if (constraints && constraints.length > 0) {
|
||||
this.validateConstraintsLimit({
|
||||
await this.validateConstraintsLimit({
|
||||
updated: constraints,
|
||||
existing: existing?.constraints ?? [],
|
||||
});
|
||||
@ -1264,7 +1267,8 @@ export class FeatureToggleService {
|
||||
|
||||
private async validateFeatureFlagLimit() {
|
||||
const currentFlagCount = await this.featureToggleStore.count();
|
||||
const limit = this.resourceLimits.featureFlags;
|
||||
const { featureFlags: limit } =
|
||||
await this.resourceLimitsService.getResourceLimits();
|
||||
if (currentFlagCount >= limit) {
|
||||
throwExceedsLimitError(this.eventBus, {
|
||||
resource: 'feature flag',
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
FavoritesService,
|
||||
GroupService,
|
||||
ProjectService,
|
||||
ResourceLimitsService,
|
||||
} from '../../services/index.js';
|
||||
import FakeGroupStore from '../../../test/fixtures/fake-group-store.js';
|
||||
import FakeEventStore from '../../../test/fixtures/fake-event-store.js';
|
||||
@ -117,10 +118,13 @@ export const createProjectService = (
|
||||
|
||||
const privateProjectChecker = createPrivateProjectChecker(db, config);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
const apiTokenService = new ApiTokenService(
|
||||
{ apiTokenStore, environmentStore },
|
||||
config,
|
||||
eventService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
|
||||
const projectReadModel = createProjectReadModel(
|
||||
@ -153,6 +157,7 @@ export const createProjectService = (
|
||||
eventService,
|
||||
privateProjectChecker,
|
||||
apiTokenService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
};
|
||||
|
||||
@ -189,10 +194,13 @@ export const createFakeProjectService = (config: IUnleashConfig) => {
|
||||
eventService,
|
||||
);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
const apiTokenService = new ApiTokenService(
|
||||
{ apiTokenStore, environmentStore },
|
||||
config,
|
||||
eventService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
|
||||
const projectReadModel = createFakeProjectReadModel();
|
||||
@ -221,6 +229,7 @@ export const createFakeProjectService = (config: IUnleashConfig) => {
|
||||
eventService,
|
||||
privateProjectChecker,
|
||||
apiTokenService,
|
||||
resourceLimitsService,
|
||||
);
|
||||
return {
|
||||
projectService,
|
||||
|
||||
@ -67,10 +67,7 @@ import { calculateAverageTimeToProd } from '../feature-toggle/time-to-production
|
||||
import type { IProjectStatsStore } from '../../types/stores/project-stats-store-type.js';
|
||||
import { uniqueByKey } from '../../util/unique.js';
|
||||
import { BadDataError, PermissionError } from '../../error/index.js';
|
||||
import type {
|
||||
ProjectDoraMetricsSchema,
|
||||
ResourceLimitsSchema,
|
||||
} from '../../openapi/index.js';
|
||||
import type { ProjectDoraMetricsSchema } from '../../openapi/index.js';
|
||||
import { checkFeatureNamingData } from '../feature-naming-pattern/feature-naming-validation.js';
|
||||
import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType.js';
|
||||
import type EventService from '../events/event-service.js';
|
||||
@ -89,6 +86,7 @@ import { canGrantProjectRole } from './can-grant-project-role.js';
|
||||
import { batchExecute } from '../../util/index.js';
|
||||
import metricsHelper from '../../util/metrics-helper.js';
|
||||
import { FUNCTION_TIME } from '../../metric-events.js';
|
||||
import type { ResourceLimitsService } from '../resource-limits/resource-limits-service.js';
|
||||
|
||||
type Days = number;
|
||||
type Count = number;
|
||||
@ -148,7 +146,7 @@ export default class ProjectService {
|
||||
|
||||
private isEnterprise: boolean;
|
||||
|
||||
private resourceLimits: ResourceLimitsSchema;
|
||||
private resourceLimitsService: ResourceLimitsService;
|
||||
|
||||
private eventBus: EventEmitter;
|
||||
|
||||
@ -193,6 +191,7 @@ export default class ProjectService {
|
||||
eventService: EventService,
|
||||
privateProjectChecker: IPrivateProjectChecker,
|
||||
apiTokenService: ApiTokenService,
|
||||
resourceLimitsService: ResourceLimitsService,
|
||||
) {
|
||||
this.projectStore = projectStore;
|
||||
this.projectOwnersReadModel = projectOwnersReadModel;
|
||||
@ -213,7 +212,7 @@ export default class ProjectService {
|
||||
this.logger = config.getLogger('services/project-service.js');
|
||||
this.flagResolver = config.flagResolver;
|
||||
this.isEnterprise = config.isEnterprise;
|
||||
this.resourceLimits = config.resourceLimits;
|
||||
this.resourceLimitsService = resourceLimitsService;
|
||||
this.eventBus = config.eventBus;
|
||||
this.projectReadModel = projectReadModel;
|
||||
this.onboardingReadModel = onboardingReadModel;
|
||||
@ -318,7 +317,9 @@ export default class ProjectService {
|
||||
}
|
||||
|
||||
async validateProjectLimit() {
|
||||
const limit = Math.max(this.resourceLimits.projects, 1);
|
||||
const { projects } =
|
||||
await this.resourceLimitsService.getResourceLimits();
|
||||
const limit = Math.max(projects, 1);
|
||||
const projectCount = await this.projectStore.count();
|
||||
|
||||
if (projectCount >= limit) {
|
||||
|
||||
14
src/lib/features/resource-limits/resource-limits-service.ts
Normal file
14
src/lib/features/resource-limits/resource-limits-service.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import type { IUnleashConfig } from '../../types/option.js';
|
||||
import type { ResourceLimitsSchema } from '../../openapi/index.js';
|
||||
|
||||
export class ResourceLimitsService {
|
||||
private config: IUnleashConfig;
|
||||
|
||||
constructor(config: IUnleashConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async getResourceLimits(): Promise<ResourceLimitsSchema> {
|
||||
return this.config.resourceLimits;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import type { Db, IUnleashConfig } from '../../types/index.js';
|
||||
import { SegmentService } from '../../services/index.js';
|
||||
import { ResourceLimitsService, SegmentService } from '../../services/index.js';
|
||||
import type { ISegmentService } from './segment-service-interface.js';
|
||||
import FeatureStrategiesStore from '../feature-toggle/feature-toggle-strategies-store.js';
|
||||
import SegmentStore from './segment-store.js';
|
||||
@ -51,6 +51,8 @@ export const createSegmentService = (
|
||||
|
||||
const eventService = createEventsService(db, config);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
return new SegmentService(
|
||||
{ segmentStore, featureStrategiesStore },
|
||||
changeRequestAccessReadModel,
|
||||
@ -58,6 +60,7 @@ export const createSegmentService = (
|
||||
config,
|
||||
eventService,
|
||||
privateProjectChecker,
|
||||
resourceLimitsService,
|
||||
);
|
||||
};
|
||||
|
||||
@ -74,6 +77,8 @@ export const createFakeSegmentService = (
|
||||
|
||||
const eventService = createFakeEventsService(config);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
return new SegmentService(
|
||||
{ segmentStore, featureStrategiesStore },
|
||||
changeRequestAccessReadModel,
|
||||
@ -81,5 +86,6 @@ export const createFakeSegmentService = (
|
||||
config,
|
||||
eventService,
|
||||
privateProjectChecker,
|
||||
resourceLimitsService,
|
||||
);
|
||||
};
|
||||
|
||||
@ -25,11 +25,9 @@ import type { IChangeRequestAccessReadModel } from '../change-request-access-ser
|
||||
import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType.js';
|
||||
import type EventService from '../events/event-service.js';
|
||||
import type { IChangeRequestSegmentUsageReadModel } from '../change-request-segment-usage-service/change-request-segment-usage-read-model.js';
|
||||
import type {
|
||||
ResourceLimitsSchema,
|
||||
UpsertSegmentSchema,
|
||||
} from '../../openapi/index.js';
|
||||
import type { UpsertSegmentSchema } from '../../openapi/index.js';
|
||||
import { throwExceedsLimitError } from '../../error/exceeds-limit-error.js';
|
||||
import type { ResourceLimitsService } from '../resource-limits/resource-limits-service.js';
|
||||
|
||||
export class SegmentService implements ISegmentService {
|
||||
private logger: Logger;
|
||||
@ -50,7 +48,7 @@ export class SegmentService implements ISegmentService {
|
||||
|
||||
private privateProjectChecker: IPrivateProjectChecker;
|
||||
|
||||
private resourceLimits: ResourceLimitsSchema;
|
||||
private resourceLimitsService: ResourceLimitsService;
|
||||
|
||||
constructor(
|
||||
{
|
||||
@ -62,6 +60,7 @@ export class SegmentService implements ISegmentService {
|
||||
config: IUnleashConfig,
|
||||
eventService: EventService,
|
||||
privateProjectChecker: IPrivateProjectChecker,
|
||||
resourceLimitsService: ResourceLimitsService,
|
||||
) {
|
||||
this.segmentStore = segmentStore;
|
||||
this.featureStrategiesStore = featureStrategiesStore;
|
||||
@ -72,7 +71,7 @@ export class SegmentService implements ISegmentService {
|
||||
this.privateProjectChecker = privateProjectChecker;
|
||||
this.logger = config.getLogger('services/segment-service.ts');
|
||||
this.flagResolver = config.flagResolver;
|
||||
this.resourceLimits = config.resourceLimits;
|
||||
this.resourceLimitsService = resourceLimitsService;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@ -136,7 +135,8 @@ export class SegmentService implements ISegmentService {
|
||||
}
|
||||
|
||||
async validateSegmentLimit() {
|
||||
const limit = this.resourceLimits.segments;
|
||||
const { segments: limit } =
|
||||
await this.resourceLimitsService.getResourceLimits();
|
||||
|
||||
const segmentCount = await this.segmentStore.count();
|
||||
|
||||
|
||||
@ -31,9 +31,9 @@ import type EventService from '../features/events/event-service.js';
|
||||
import { addMinutes, isPast } from 'date-fns';
|
||||
import metricsHelper from '../util/metrics-helper.js';
|
||||
import { FUNCTION_TIME } from '../metric-events.js';
|
||||
import type { ResourceLimitsSchema } from '../openapi/index.js';
|
||||
import { throwExceedsLimitError } from '../error/exceeds-limit-error.js';
|
||||
import type EventEmitter from 'events';
|
||||
import type { ResourceLimitsService } from '../features/resource-limits/resource-limits-service.js';
|
||||
|
||||
const resolveTokenPermissions = (tokenType: string) => {
|
||||
if (tokenType === ApiTokenType.ADMIN) {
|
||||
@ -73,7 +73,7 @@ export class ApiTokenService {
|
||||
|
||||
private timer: Function;
|
||||
|
||||
private resourceLimits: ResourceLimitsSchema;
|
||||
private resourceLimitsService: ResourceLimitsService;
|
||||
|
||||
private eventBus: EventEmitter;
|
||||
|
||||
@ -84,20 +84,17 @@ export class ApiTokenService {
|
||||
}: Pick<IUnleashStores, 'apiTokenStore' | 'environmentStore'>,
|
||||
config: Pick<
|
||||
IUnleashConfig,
|
||||
| 'getLogger'
|
||||
| 'authentication'
|
||||
| 'flagResolver'
|
||||
| 'eventBus'
|
||||
| 'resourceLimits'
|
||||
'getLogger' | 'authentication' | 'flagResolver' | 'eventBus'
|
||||
>,
|
||||
eventService: EventService,
|
||||
resourceLimitsService: ResourceLimitsService,
|
||||
) {
|
||||
this.store = apiTokenStore;
|
||||
this.eventService = eventService;
|
||||
this.resourceLimitsService = resourceLimitsService;
|
||||
this.environmentStore = environmentStore;
|
||||
this.flagResolver = config.flagResolver;
|
||||
this.logger = config.getLogger('/services/api-token-service.ts');
|
||||
this.resourceLimits = config.resourceLimits;
|
||||
if (!this.flagResolver.isEnabled('useMemoizedActiveTokens')) {
|
||||
// This is probably not needed because the scheduler will run it
|
||||
this.fetchActiveTokens();
|
||||
@ -321,7 +318,8 @@ export class ApiTokenService {
|
||||
|
||||
private async validateApiTokenLimit() {
|
||||
const currentTokenCount = await this.store.count();
|
||||
const limit = this.resourceLimits.apiTokens;
|
||||
const { apiTokens: limit } =
|
||||
await this.resourceLimitsService.getResourceLimits();
|
||||
if (currentTokenCount >= limit) {
|
||||
throwExceedsLimitError(this.eventBus, {
|
||||
resource: 'api token',
|
||||
|
||||
@ -171,6 +171,7 @@ import { UnknownFlagsService } from '../features/metrics/unknown-flags/unknown-f
|
||||
import type FeatureLinkService from '../features/feature-links/feature-link-service.js';
|
||||
import { createUserService } from '../features/users/createUserService.js';
|
||||
import { UiConfigService } from '../ui-config/ui-config-service.js';
|
||||
import { ResourceLimitsService } from '../features/resource-limits/resource-limits-service.js';
|
||||
|
||||
export const createServices = (
|
||||
stores: IUnleashStores,
|
||||
@ -205,6 +206,8 @@ export const createServices = (
|
||||
|
||||
const unknownFlagsService = new UnknownFlagsService(stores, config);
|
||||
|
||||
const resourceLimitsService = new ResourceLimitsService(config);
|
||||
|
||||
// Initialize custom metrics service
|
||||
const customMetricsService = new CustomMetricsService(config);
|
||||
|
||||
@ -283,6 +286,7 @@ export const createServices = (
|
||||
config,
|
||||
eventService,
|
||||
privateProjectChecker,
|
||||
resourceLimitsService,
|
||||
);
|
||||
|
||||
const clientInstanceService = new ClientInstanceService(
|
||||
@ -449,6 +453,7 @@ export const createServices = (
|
||||
frontendApiService,
|
||||
maintenanceService,
|
||||
sessionService,
|
||||
resourceLimitsService,
|
||||
});
|
||||
|
||||
return {
|
||||
@ -525,6 +530,7 @@ export const createServices = (
|
||||
featureLinkService,
|
||||
unknownFlagsService,
|
||||
uiConfigService,
|
||||
resourceLimitsService,
|
||||
};
|
||||
};
|
||||
|
||||
@ -581,6 +587,8 @@ export {
|
||||
UniqueConnectionService,
|
||||
FeatureLifecycleReadModel,
|
||||
UnknownFlagsService,
|
||||
UiConfigService,
|
||||
ResourceLimitsService,
|
||||
};
|
||||
|
||||
export interface IUnleashServices {
|
||||
@ -657,4 +665,5 @@ export interface IUnleashServices {
|
||||
featureLinkService: FeatureLinkService;
|
||||
unknownFlagsService: UnknownFlagsService;
|
||||
uiConfigService: UiConfigService;
|
||||
resourceLimitsService: ResourceLimitsService;
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
simpleAuthSettingsKey,
|
||||
} from '../types/settings/simple-auth-settings.js';
|
||||
import version from '../util/version.js';
|
||||
import type { ResourceLimitsService } from '../features/resource-limits/resource-limits-service.js';
|
||||
|
||||
export class UiConfigService {
|
||||
private config: IUnleashConfig;
|
||||
@ -33,6 +34,8 @@ export class UiConfigService {
|
||||
|
||||
private maintenanceService: MaintenanceService;
|
||||
|
||||
private resourceLimitsService: ResourceLimitsService;
|
||||
|
||||
private flagResolver: IFlagResolver;
|
||||
|
||||
constructor(
|
||||
@ -44,6 +47,7 @@ export class UiConfigService {
|
||||
frontendApiService,
|
||||
maintenanceService,
|
||||
sessionService,
|
||||
resourceLimitsService,
|
||||
}: Pick<
|
||||
IUnleashServices,
|
||||
| 'versionService'
|
||||
@ -52,6 +56,7 @@ export class UiConfigService {
|
||||
| 'frontendApiService'
|
||||
| 'maintenanceService'
|
||||
| 'sessionService'
|
||||
| 'resourceLimitsService'
|
||||
>,
|
||||
) {
|
||||
this.config = config;
|
||||
@ -62,6 +67,7 @@ export class UiConfigService {
|
||||
this.frontendApiService = frontendApiService;
|
||||
this.maintenanceService = maintenanceService;
|
||||
this.sessionService = sessionService;
|
||||
this.resourceLimitsService = resourceLimitsService;
|
||||
}
|
||||
|
||||
async getMaxSessionsCount(): Promise<number> {
|
||||
@ -114,7 +120,8 @@ export class UiConfigService {
|
||||
frontendApiOrigins: frontendSettings.frontendApiOrigins,
|
||||
versionInfo: await this.versionService.getVersionInfo(),
|
||||
prometheusAPIAvailable: this.config.prometheusApi !== undefined,
|
||||
resourceLimits: this.config.resourceLimits,
|
||||
resourceLimits:
|
||||
await this.resourceLimitsService.getResourceLimits(),
|
||||
disablePasswordAuth,
|
||||
maintenanceMode,
|
||||
feedbackUriPath: this.config.feedbackUriPath,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user