mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-18 13:48:58 +02:00
change update to upsert
Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
6de0414732
commit
f64ba6b60c
@ -171,24 +171,37 @@ export default class FeatureToggleStore implements IFeatureToggleStore {
|
||||
return present;
|
||||
}
|
||||
|
||||
private upsert = (params: any) => {
|
||||
const { table, object, constraint } = params;
|
||||
const insert = this.db(table).insert(object);
|
||||
const update = this.db.queryBuilder().update(object);
|
||||
return this.db
|
||||
.raw(`? ON CONFLICT ${constraint} DO ? returning *`, [
|
||||
insert,
|
||||
update,
|
||||
])
|
||||
.get('rows')
|
||||
.get(0);
|
||||
};
|
||||
|
||||
async setLastSeen(data: LastSeenInput[]): Promise<void> {
|
||||
const now = new Date();
|
||||
const environmentArrays = this.mapMetricDataToEnvBuckets(data);
|
||||
try {
|
||||
for (const env of Object.keys(environmentArrays)) {
|
||||
const toggleNames = environmentArrays[env].sort();
|
||||
await this.db(FEATURE_ENVIRONMENTS_METRICS_TABLE)
|
||||
.upsert({ last_seen_at: now })
|
||||
.where('environment', env)
|
||||
.whereIn(
|
||||
'feature_name',
|
||||
this.db(FEATURE_ENVIRONMENTS_METRICS_TABLE)
|
||||
.select('feature_name')
|
||||
.whereIn('feature_name', toggleNames)
|
||||
.forUpdate()
|
||||
.skipLocked(),
|
||||
);
|
||||
const enhancedData = data.map((value) => ({
|
||||
feature_name: value.featureName,
|
||||
last_seen_at: now,
|
||||
environment: value.environment,
|
||||
}));
|
||||
const dataToPersist: typeof enhancedData = [];
|
||||
for (const input of enhancedData) {
|
||||
if (await this.exists(input.feature_name)) {
|
||||
dataToPersist.push(input);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await this.db(FEATURE_ENVIRONMENTS_METRICS_TABLE)
|
||||
.insert(dataToPersist)
|
||||
.onConflict(['feature_name', 'environment'])
|
||||
.merge(['last_seen_at']);
|
||||
} catch (err) {
|
||||
this.logger.error('Could not update lastSeen, error: ', err);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ export class LastSeenService {
|
||||
.filter(
|
||||
(clientMetric) => clientMetric.yes > 0 || clientMetric.no > 0,
|
||||
)
|
||||
.forEach((clientMetric) => {
|
||||
.forEach(async (clientMetric) => {
|
||||
const key = `${clientMetric.featureName}:${clientMetric.environment}`;
|
||||
this.lastSeenToggles.set(key, {
|
||||
featureName: clientMetric.featureName,
|
||||
|
@ -129,3 +129,46 @@ test('Should not update anything for 0 toggles', async () => {
|
||||
|
||||
service.destroy();
|
||||
});
|
||||
|
||||
test('Should handle 1000 toggle updates', async () => {
|
||||
// jest.useFakeTimers();
|
||||
const service = new LastSeenService(stores, config, 30);
|
||||
const time = Date.now();
|
||||
for (let i = 0; i <= 1000; i++) {
|
||||
await stores.featureToggleStore.create('default', { name: `tb${i}` });
|
||||
}
|
||||
const metrics: IClientMetricsEnv[] = [];
|
||||
|
||||
for (let i = 0; i < 999; i++) {
|
||||
metrics.push({
|
||||
featureName: `tb${i}`,
|
||||
appName: 'some-App',
|
||||
environment: 'default',
|
||||
timestamp: new Date(time),
|
||||
yes: 1,
|
||||
no: 0,
|
||||
});
|
||||
}
|
||||
|
||||
metrics.push({
|
||||
featureName: 'tb1000',
|
||||
appName: 'some-App',
|
||||
environment: 'default',
|
||||
timestamp: new Date(time),
|
||||
yes: 0,
|
||||
no: 0,
|
||||
});
|
||||
|
||||
service.updateLastSeen(metrics);
|
||||
|
||||
// bypass interval waiting
|
||||
await service.store();
|
||||
|
||||
const t1 = await stores.featureToggleStore.get('tb1');
|
||||
const t2 = await stores.featureToggleStore.get('tb1000');
|
||||
|
||||
expect(t2.lastSeenAt).toBeNull();
|
||||
expect(t1.lastSeenAt.getTime()).toBeGreaterThanOrEqual(time);
|
||||
|
||||
service.destroy();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user