Skip to content

Commit 3c8f3b5

Browse files
authored
fix: Include connectionId in metadata cache key (#1272)
Closes HDX-2573 This PR adds connection ID to the metadata cache key, to ensure that metadata is not shared across tables with the same name in different connections. For example, previously when switching between otel_logs tables in different connections, filter values would not reload: https://github.com/user-attachments/assets/d3edb243-4564-438f-9fec-c400fdfbd5b3 Now they will: https://github.com/user-attachments/assets/19b0f022-8e30-412e-8a06-3d9812794219
1 parent 3d832ad commit 3c8f3b5

File tree

3 files changed

+50
-45
lines changed

3 files changed

+50
-45
lines changed

.changeset/mean-ghosts-leave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/common-utils": patch
3+
---
4+
5+
fix: Include connectionId in metadata cache key

packages/common-utils/src/__tests__/metadata.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ describe('Metadata', () => {
198198

199199
// Setup the cache to return the mock data
200200
mockCache.getOrFetch.mockImplementation((key, queryFn) => {
201-
if (key === 'test_db.test_table.metadata') {
201+
if (key === 'test_connection.test_db.test_table.metadata') {
202202
return Promise.resolve(mockTableMetadata);
203203
}
204204
return queryFn();
@@ -212,7 +212,7 @@ describe('Metadata', () => {
212212

213213
// Verify the cache was called with the right key
214214
expect(mockCache.getOrFetch).toHaveBeenCalledWith(
215-
'test_db.test_table.metadata',
215+
'test_connection.test_db.test_table.metadata',
216216
expect.any(Function),
217217
);
218218

packages/common-utils/src/metadata.ts

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,21 @@ export class Metadata {
129129
cache: MetadataCache;
130130
connectionId: string;
131131
}) {
132-
return cache.getOrFetch(`${database}.${table}.metadata`, async () => {
133-
const sql = chSql`SELECT * FROM system.tables where database = ${{ String: database }} AND name = ${{ String: table }}`;
134-
const json = await this.clickhouseClient
135-
.query<'JSON'>({
136-
connectionId,
137-
query: sql.sql,
138-
query_params: sql.params,
139-
clickhouse_settings: this.getClickHouseSettings(),
140-
})
141-
.then(res => res.json<TableMetadata>());
142-
return json.data[0];
143-
});
132+
return cache.getOrFetch(
133+
`${connectionId}.${database}.${table}.metadata`,
134+
async () => {
135+
const sql = chSql`SELECT * FROM system.tables where database = ${{ String: database }} AND name = ${{ String: table }}`;
136+
const json = await this.clickhouseClient
137+
.query<'JSON'>({
138+
connectionId,
139+
query: sql.sql,
140+
query_params: sql.params,
141+
clickhouse_settings: this.getClickHouseSettings(),
142+
})
143+
.then(res => res.json<TableMetadata>());
144+
return json.data[0];
145+
},
146+
);
144147
}
145148

146149
async getColumns({
@@ -153,7 +156,7 @@ export class Metadata {
153156
connectionId: string;
154157
}) {
155158
return this.cache.getOrFetch<ColumnMeta[]>(
156-
`${databaseName}.${tableName}.columns`,
159+
`${connectionId}.${databaseName}.${tableName}.columns`,
157160
async () => {
158161
const sql = chSql`DESCRIBE ${tableExpr({ database: databaseName, table: tableName })}`;
159162
const columns = await this.clickhouseClient
@@ -240,8 +243,8 @@ export class Metadata {
240243
metricName?: string;
241244
}) {
242245
const cacheKey = metricName
243-
? `${databaseName}.${tableName}.${column}.${metricName}.keys`
244-
: `${databaseName}.${tableName}.${column}.keys`;
246+
? `${connectionId}.${databaseName}.${tableName}.${column}.${metricName}.keys`
247+
: `${connectionId}.${databaseName}.${tableName}.${column}.keys`;
245248
const cachedKeys = this.cache.get<string[]>(cacheKey);
246249

247250
if (cachedKeys != null) {
@@ -351,8 +354,8 @@ export class Metadata {
351354
// HDX-2480 delete line below to reenable json filters
352355
return []; // Need to disable JSON keys for the time being.
353356
const cacheKey = metricName
354-
? `${databaseName}.${tableName}.${column}.${metricName}.keys`
355-
: `${databaseName}.${tableName}.${column}.keys`;
357+
? `${connectionId}.${databaseName}.${tableName}.${column}.${metricName}.keys`
358+
: `${connectionId}.${databaseName}.${tableName}.${column}.keys`;
356359

357360
return this.cache.getOrFetch<{ key: string; chType: string }[]>(
358361
cacheKey,
@@ -420,9 +423,9 @@ export class Metadata {
420423
maxValues?: number;
421424
connectionId: string;
422425
}) {
423-
const cachedValues = this.cache.get<string[]>(
424-
`${databaseName}.${tableName}.${column}.${key}.values`,
425-
);
426+
const cacheKey = `${connectionId}.${databaseName}.${tableName}.${column}.${key}.values`;
427+
428+
const cachedValues = this.cache.get<string[]>(cacheKey);
426429

427430
if (cachedValues != null) {
428431
return cachedValues;
@@ -450,28 +453,25 @@ export class Metadata {
450453
}}
451454
`;
452455

453-
return this.cache.getOrFetch<string[]>(
454-
`${databaseName}.${tableName}.${column}.${key}.values`,
455-
async () => {
456-
const values = await this.clickhouseClient
457-
.query<'JSON'>({
458-
query: sql.sql,
459-
query_params: sql.params,
460-
connectionId,
461-
clickhouse_settings: {
462-
max_rows_to_read: String(
463-
this.getClickHouseSettings().max_rows_to_read ??
464-
DEFAULT_METADATA_MAX_ROWS_TO_READ,
465-
),
466-
read_overflow_mode: 'break',
467-
...this.getClickHouseSettings(),
468-
},
469-
})
470-
.then(res => res.json<Record<string, unknown>>())
471-
.then(d => d.data.map(row => row.value as string));
472-
return values;
473-
},
474-
);
456+
return this.cache.getOrFetch<string[]>(cacheKey, async () => {
457+
const values = await this.clickhouseClient
458+
.query<'JSON'>({
459+
query: sql.sql,
460+
query_params: sql.params,
461+
connectionId,
462+
clickhouse_settings: {
463+
max_rows_to_read: String(
464+
this.getClickHouseSettings().max_rows_to_read ??
465+
DEFAULT_METADATA_MAX_ROWS_TO_READ,
466+
),
467+
read_overflow_mode: 'break',
468+
...this.getClickHouseSettings(),
469+
},
470+
})
471+
.then(res => res.json<Record<string, unknown>>())
472+
.then(d => d.data.map(row => row.value as string));
473+
return values;
474+
});
475475
}
476476

477477
async getAllFields({
@@ -666,7 +666,7 @@ export class Metadata {
666666
disableRowLimit?: boolean;
667667
}) {
668668
return this.cache.getOrFetch(
669-
`${chartConfig.from.databaseName}.${chartConfig.from.tableName}.${keys.join(',')}.${chartConfig.dateRange.toString()}.${disableRowLimit}.values`,
669+
`${chartConfig.connection}.${chartConfig.from.databaseName}.${chartConfig.from.tableName}.${keys.join(',')}.${chartConfig.dateRange.toString()}.${disableRowLimit}.values`,
670670
async () => {
671671
const selectClause = keys
672672
.map((k, i) => `groupUniqArray(${limit})(${k}) AS param${i}`)

0 commit comments

Comments
 (0)