mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-12 01:17:04 +02:00
feat: remove inactive applications (#9835)
This commit is contained in:
parent
bffaab5560
commit
d24bcff404
@ -449,4 +449,16 @@ export default class ClientApplicationsStore
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async removeInactiveApplications(): Promise<number> {
|
||||||
|
const rows = await this.db(TABLE)
|
||||||
|
.whereRaw("seen_at < now() - interval '30 days'")
|
||||||
|
.del();
|
||||||
|
|
||||||
|
if (rows > 0) {
|
||||||
|
this.logger.debug(`Deleted ${rows} applications`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,13 @@ export default class ClientInstanceService {
|
|||||||
return this.clientInstanceStore.removeInstancesOlderThanTwoDays();
|
return this.clientInstanceStore.removeInstancesOlderThanTwoDays();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeInactiveApplications(): Promise<number> {
|
||||||
|
if (this.flagResolver.isEnabled('removeInactiveApplications')) {
|
||||||
|
return this.clientApplicationsStore.removeInactiveApplications();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
async getOutdatedSdks(): Promise<OutdatedSdksSchema['sdks']> {
|
async getOutdatedSdks(): Promise<OutdatedSdksSchema['sdks']> {
|
||||||
const sdkApps = await this.clientInstanceStore.groupApplicationsBySdk();
|
const sdkApps = await this.clientInstanceStore.groupApplicationsBySdk();
|
||||||
|
|
||||||
|
@ -78,6 +78,14 @@ export const scheduleServices = async (
|
|||||||
'removeInstancesOlderThanTwoDays',
|
'removeInstancesOlderThanTwoDays',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
schedulerService.schedule(
|
||||||
|
clientInstanceService.removeInactiveApplications.bind(
|
||||||
|
clientInstanceService,
|
||||||
|
),
|
||||||
|
hoursToMilliseconds(24),
|
||||||
|
'removeInactiveApplications',
|
||||||
|
);
|
||||||
|
|
||||||
schedulerService.schedule(
|
schedulerService.schedule(
|
||||||
clientInstanceService.bulkAdd.bind(clientInstanceService),
|
clientInstanceService.bulkAdd.bind(clientInstanceService),
|
||||||
secondsToMilliseconds(5),
|
secondsToMilliseconds(5),
|
||||||
|
@ -69,7 +69,8 @@ export type IFlagKey =
|
|||||||
| 'newStrategyDropdown'
|
| 'newStrategyDropdown'
|
||||||
| 'flagsOverviewSearch'
|
| 'flagsOverviewSearch'
|
||||||
| 'flagsReleaseManagementUI'
|
| 'flagsReleaseManagementUI'
|
||||||
| 'cleanupReminder';
|
| 'cleanupReminder'
|
||||||
|
| 'removeInactiveApplications';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -330,6 +331,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_CLEANUP_REMINDER,
|
process.env.UNLEASH_EXPERIMENTAL_CLEANUP_REMINDER,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
removeInactiveApplications: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_REMOVE_INACTIVE_APPLICATIONS,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -44,4 +44,5 @@ export interface IClientApplicationsStore
|
|||||||
getUnannounced(): Promise<IClientApplication[]>;
|
getUnannounced(): Promise<IClientApplication[]>;
|
||||||
setUnannouncedToAnnounced(): Promise<IClientApplication[]>;
|
setUnannouncedToAnnounced(): Promise<IClientApplication[]>;
|
||||||
getApplicationOverview(appName: string): Promise<IApplicationOverview>;
|
getApplicationOverview(appName: string): Promise<IApplicationOverview>;
|
||||||
|
removeInactiveApplications(): Promise<number>;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import type {
|
|||||||
IUnleashStores,
|
IUnleashStores,
|
||||||
} from '../../../lib/types';
|
} from '../../../lib/types';
|
||||||
import type { IClientApplication } from '../../../lib/types/stores/client-applications-store';
|
import type { IClientApplication } from '../../../lib/types/stores/client-applications-store';
|
||||||
|
import { subDays } from 'date-fns';
|
||||||
|
|
||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
let stores: IUnleashStores;
|
let stores: IUnleashStores;
|
||||||
@ -175,3 +176,33 @@ test('Multi row merge also works', async () => {
|
|||||||
expect(s!.icon).toBe('red');
|
expect(s!.icon).toBe('red');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Remove inactive applications', async () => {
|
||||||
|
const clientRegistration = {
|
||||||
|
appName: faker.internet.domainName(),
|
||||||
|
instanceId: faker.datatype.uuid(),
|
||||||
|
strategies: ['default'],
|
||||||
|
started: Date.now(),
|
||||||
|
interval: faker.datatype.number(),
|
||||||
|
sdkVersion: '3.11.2',
|
||||||
|
icon: '',
|
||||||
|
description: faker.company.catchPhrase(),
|
||||||
|
color: faker.internet.color(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await clientApplicationsStore.upsert({
|
||||||
|
...clientRegistration,
|
||||||
|
lastSeen: subDays(Date.now(), 29),
|
||||||
|
});
|
||||||
|
const noRemovedItems =
|
||||||
|
await clientApplicationsStore.removeInactiveApplications();
|
||||||
|
expect(noRemovedItems).toBe(0);
|
||||||
|
|
||||||
|
await clientApplicationsStore.upsert({
|
||||||
|
...clientRegistration,
|
||||||
|
lastSeen: subDays(Date.now(), 30),
|
||||||
|
});
|
||||||
|
const removedItems =
|
||||||
|
await clientApplicationsStore.removeInactiveApplications();
|
||||||
|
expect(removedItems).toBe(1);
|
||||||
|
});
|
||||||
|
@ -82,4 +82,8 @@ export default class FakeClientApplicationsStore
|
|||||||
getApplicationOverview(appName: string): Promise<IApplicationOverview> {
|
getApplicationOverview(appName: string): Promise<IApplicationOverview> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeInactiveApplications(): Promise<number> {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user