mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-10 17:53:36 +02:00
fix: dedupe duplicates on batchInsert
This commit is contained in:
parent
2d04088c23
commit
c7689ddf69
@ -79,21 +79,29 @@ export class ClientMetricsStoreV2 implements IClientMetricsStoreV2 {
|
|||||||
// Nothing to do!
|
// Nothing to do!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this function will collapse metrics before sending it to the database.
|
||||||
async batchInsertMetrics(metrics: IClientMetricsEnv[]): Promise<void> {
|
async batchInsertMetrics(metrics: IClientMetricsEnv[]): Promise<void> {
|
||||||
const rows = metrics.map(toRow);
|
const rows = metrics.map(toRow);
|
||||||
|
|
||||||
|
const batch = rows.reduce((prev, curr) => {
|
||||||
|
// eslint-disable-next-line prettier/prettier
|
||||||
|
const key = `${curr.feature_name}_${curr.app_name}_${curr.environment}_${curr.timestamp.getTime()}`;
|
||||||
|
if (prev[key]) {
|
||||||
|
prev[key].yes += curr.yes;
|
||||||
|
prev[key].no += curr.no;
|
||||||
|
} else {
|
||||||
|
prev[key] = curr;
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}, {});
|
||||||
|
|
||||||
// Consider rewriting to SQL batch!
|
// Consider rewriting to SQL batch!
|
||||||
for (const row of rows) {
|
|
||||||
const insert = this.db<ClientMetricsEnvTable>(TABLE)
|
const insert = this.db<ClientMetricsEnvTable>(TABLE)
|
||||||
.insert(row)
|
.insert(Object.values(batch))
|
||||||
.toQuery();
|
.toQuery();
|
||||||
|
|
||||||
const query = `${insert.toString()} ON CONFLICT (feature_name, app_name, environment, timestamp)
|
const query = `${insert.toString()} ON CONFLICT (feature_name, app_name, environment, timestamp) DO UPDATE SET "yes" = "client_metrics_env"."yes" + EXCLUDED.yes, "no" = "client_metrics_env"."no" + EXCLUDED.no`;
|
||||||
DO UPDATE SET
|
await this.db.raw(query);
|
||||||
"yes" = "client_metrics_env"."yes" + ?,
|
|
||||||
"no" = "client_metrics_env"."no" + ?`;
|
|
||||||
await this.db.raw(query, [row.yes, row.no]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMetricsForFeatureToggle(
|
async getMetricsForFeatureToggle(
|
||||||
|
@ -4,10 +4,10 @@ export interface IClientMetricsEnvKey {
|
|||||||
featureName: string;
|
featureName: string;
|
||||||
appName: string;
|
appName: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
|
timestamp: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IClientMetricsEnv extends IClientMetricsEnvKey {
|
export interface IClientMetricsEnv extends IClientMetricsEnvKey {
|
||||||
timestamp: Date;
|
|
||||||
yes: number;
|
yes: number;
|
||||||
no: number;
|
no: number;
|
||||||
}
|
}
|
||||||
|
@ -192,3 +192,25 @@ test('Should get toggle metrics', async () => {
|
|||||||
expect(savedMetrics[0].yes).toBe(4950);
|
expect(savedMetrics[0].yes).toBe(4950);
|
||||||
expect(savedMetrics[0].no).toBe(5050);
|
expect(savedMetrics[0].no).toBe(5050);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Should insert 1500 feature toggle metrics', async () => {
|
||||||
|
const metrics: IClientMetricsEnv[] = [];
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
for (let i = 0; i < 1500; i++) {
|
||||||
|
metrics.push({
|
||||||
|
featureName: `demo-${i}`,
|
||||||
|
appName: `web`,
|
||||||
|
environment: 'dev',
|
||||||
|
timestamp: date,
|
||||||
|
yes: 2,
|
||||||
|
no: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await clientMetricsStore.batchInsertMetrics(metrics);
|
||||||
|
const savedMetrics = await clientMetricsStore.getAll();
|
||||||
|
|
||||||
|
expect(savedMetrics).toHaveLength(1500);
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user