mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-07 01:16:28 +02:00
fix: version-service should not use process.nextTick (#6124)
In the beginning we used process.nextTick() as a trick to load some data initally in the constructor of a service. This is a bad pattern and we should generally avoid any async operations in the constructor. Today we have two alternatives: 1. Defer loading until data is needed (wrap it in async) 2. Use the schdule-service.
This commit is contained in:
parent
354b88383c
commit
897500dd54
@ -211,7 +211,7 @@ export class InstanceStatsService {
|
|||||||
* use getStatsSnapshot for low latency, sacrificing data-freshness
|
* use getStatsSnapshot for low latency, sacrificing data-freshness
|
||||||
*/
|
*/
|
||||||
async getStats(): Promise<InstanceStats> {
|
async getStats(): Promise<InstanceStats> {
|
||||||
const versionInfo = this.versionService.getVersionInfo();
|
const versionInfo = await this.versionService.getVersionInfo();
|
||||||
const [
|
const [
|
||||||
featureToggles,
|
featureToggles,
|
||||||
users,
|
users,
|
||||||
|
@ -167,7 +167,7 @@ class ConfigController extends Controller {
|
|||||||
segmentValuesLimit: this.config.segmentValuesLimit,
|
segmentValuesLimit: this.config.segmentValuesLimit,
|
||||||
strategySegmentsLimit: this.config.strategySegmentsLimit,
|
strategySegmentsLimit: this.config.strategySegmentsLimit,
|
||||||
frontendApiOrigins: frontendSettings.frontendApiOrigins,
|
frontendApiOrigins: frontendSettings.frontendApiOrigins,
|
||||||
versionInfo: this.versionService.getVersionInfo(),
|
versionInfo: await this.versionService.getVersionInfo(),
|
||||||
networkViewEnabled: this.config.prometheusApi !== undefined,
|
networkViewEnabled: this.config.prometheusApi !== undefined,
|
||||||
disablePasswordAuth,
|
disablePasswordAuth,
|
||||||
maintenanceMode,
|
maintenanceMode,
|
||||||
|
@ -44,7 +44,7 @@ test('yields current versions', async () => {
|
|||||||
createFakeGetProductionChanges(),
|
createFakeGetProductionChanges(),
|
||||||
);
|
);
|
||||||
await service.checkLatestVersion();
|
await service.checkLatestVersion();
|
||||||
const versionInfo = service.getVersionInfo();
|
const versionInfo = await service.getVersionInfo();
|
||||||
expect(scope.isDone()).toEqual(true);
|
expect(scope.isDone()).toEqual(true);
|
||||||
expect(versionInfo.current.oss).toBe(version);
|
expect(versionInfo.current.oss).toBe(version);
|
||||||
expect(versionInfo.current.enterprise).toBeFalsy();
|
expect(versionInfo.current.enterprise).toBeFalsy();
|
||||||
@ -83,7 +83,7 @@ test('supports setting enterprise version as well', async () => {
|
|||||||
createFakeGetProductionChanges(),
|
createFakeGetProductionChanges(),
|
||||||
);
|
);
|
||||||
await service.checkLatestVersion();
|
await service.checkLatestVersion();
|
||||||
const versionInfo = service.getVersionInfo();
|
const versionInfo = await service.getVersionInfo();
|
||||||
expect(scope.isDone()).toEqual(true);
|
expect(scope.isDone()).toEqual(true);
|
||||||
expect(versionInfo.current.oss).toBe(version);
|
expect(versionInfo.current.oss).toBe(version);
|
||||||
expect(versionInfo.current.enterprise).toBe(enterpriseVersion);
|
expect(versionInfo.current.enterprise).toBe(enterpriseVersion);
|
||||||
@ -122,7 +122,7 @@ test('if version check is not enabled should not make any calls', async () => {
|
|||||||
createFakeGetProductionChanges(),
|
createFakeGetProductionChanges(),
|
||||||
);
|
);
|
||||||
await service.checkLatestVersion();
|
await service.checkLatestVersion();
|
||||||
const versionInfo = service.getVersionInfo();
|
const versionInfo = await service.getVersionInfo();
|
||||||
expect(scope.isDone()).toEqual(false);
|
expect(scope.isDone()).toEqual(false);
|
||||||
expect(versionInfo.current.oss).toBe(version);
|
expect(versionInfo.current.oss).toBe(version);
|
||||||
expect(versionInfo.current.enterprise).toBe(enterpriseVersion);
|
expect(versionInfo.current.enterprise).toBe(enterpriseVersion);
|
||||||
|
@ -178,35 +178,36 @@ export default class VersionService {
|
|||||||
this.telemetryEnabled = telemetry;
|
this.telemetryEnabled = telemetry;
|
||||||
this.versionCheckUrl = versionCheck.url;
|
this.versionCheckUrl = versionCheck.url;
|
||||||
this.isLatest = true;
|
this.isLatest = true;
|
||||||
process.nextTick(() => this.setup());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup(): Promise<void> {
|
private async readInstanceId(): Promise<string | undefined> {
|
||||||
await this.readInstanceId();
|
|
||||||
await this.checkLatestVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async readInstanceId(): Promise<void> {
|
|
||||||
try {
|
try {
|
||||||
const { id } = (await this.settingStore.get<{ id: string }>(
|
const { id } = (await this.settingStore.get<{ id: string }>(
|
||||||
'instanceInfo',
|
'instanceInfo',
|
||||||
)) ?? { id: undefined };
|
)) ?? { id: undefined };
|
||||||
this.instanceId = id;
|
return id;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn('Could not find instanceInfo', err);
|
this.logger.warn('Could not find instanceInfo', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getInstanceId() {
|
async getInstanceId() {
|
||||||
|
if (!this.instanceId) {
|
||||||
|
this.instanceId = await this.readInstanceId();
|
||||||
|
}
|
||||||
return this.instanceId;
|
return this.instanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkLatestVersion(): Promise<void> {
|
async checkLatestVersion(): Promise<void> {
|
||||||
|
const instanceId = await this.getInstanceId();
|
||||||
|
this.logger.debug(
|
||||||
|
`Checking for newest version for instanceId=${instanceId}`,
|
||||||
|
);
|
||||||
if (this.enabled) {
|
if (this.enabled) {
|
||||||
try {
|
try {
|
||||||
const versionPayload: any = {
|
const versionPayload: any = {
|
||||||
versions: this.current,
|
versions: this.current,
|
||||||
instanceId: this.instanceId,
|
instanceId: instanceId,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.telemetryEnabled) {
|
if (this.telemetryEnabled) {
|
||||||
@ -282,7 +283,7 @@ export default class VersionService {
|
|||||||
this.userStats(),
|
this.userStats(),
|
||||||
this.productionChanges(),
|
this.productionChanges(),
|
||||||
]);
|
]);
|
||||||
const versionInfo = this.getVersionInfo();
|
const versionInfo = await this.getVersionInfo();
|
||||||
const customStrategies =
|
const customStrategies =
|
||||||
await this.strategyStore.getEditableStrategies();
|
await this.strategyStore.getEditableStrategies();
|
||||||
const customStrategiesInUse =
|
const customStrategiesInUse =
|
||||||
@ -351,15 +352,13 @@ export default class VersionService {
|
|||||||
return settings?.enabled || false;
|
return settings?.enabled || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getVersionInfo(): IVersionHolder {
|
async getVersionInfo(): Promise<IVersionHolder> {
|
||||||
|
const instanceId = await this.getInstanceId();
|
||||||
return {
|
return {
|
||||||
current: this.current,
|
current: this.current,
|
||||||
latest: this.latest || {},
|
latest: this.latest || {},
|
||||||
isLatest: this.isLatest,
|
isLatest: this.isLatest,
|
||||||
// @ts-ignore instance id can be undefined but not on the version. What should we do is still unclear.
|
instanceId: instanceId || 'unresolved-instance-id',
|
||||||
instanceId: this.instanceId,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = VersionService;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user