Skip to content

Commit ec4d032

Browse files
committed
feat(clickhouse): queue activity ranking queries
1 parent ab0284a commit ec4d032

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

internal-packages/clickhouse/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import {
3636
insertQueueMetricsRaw,
3737
getQueueListMetricsSummary,
3838
getQueueDepthSparklines,
39+
getQueueRankingPage,
40+
getQueueRankingCount,
3941
} from "./queueMetrics.js";
4042
import {
4143
getSessionTagsQueryBuilder,
@@ -271,6 +273,8 @@ export class ClickHouse {
271273
insertRaw: insertQueueMetricsRaw(this.writer),
272274
listSummary: getQueueListMetricsSummary(this.reader),
273275
depthSparklines: getQueueDepthSparklines(this.reader),
276+
rankingPage: getQueueRankingPage(this.reader),
277+
rankingCount: getQueueRankingCount(this.reader),
274278
};
275279
}
276280

internal-packages/clickhouse/src/queueMetrics.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,66 @@ export function getQueueDepthSparklines(reader: ClickhouseReader) {
105105
});
106106
}
107107

108+
const QueueRankingParams = z.object({
109+
organizationId: z.string(),
110+
projectId: z.string(),
111+
environmentId: z.string(),
112+
startTime: z.string(),
113+
/** 1 = rank by peak backlog only; 0 = backlog + running ("busiest"). */
114+
byQueuedOnly: z.number(),
115+
nameContains: z.string(),
116+
limit: z.number(),
117+
offset: z.number(),
118+
});
119+
120+
const QueueRankingRow = z.object({
121+
queue_name: z.string(),
122+
});
123+
124+
const RANKING_WHERE = `organization_id = {organizationId: String}
125+
AND project_id = {projectId: String}
126+
AND environment_id = {environmentId: String}
127+
AND bucket_start >= {startTime: DateTime}
128+
AND queue_name != '__overflow__'
129+
AND ({nameContains: String} = '' OR positionCaseInsensitive(queue_name, {nameContains: String}) > 0)`;
130+
131+
/** Queue names ranked by recent activity, for relevance-ordered list pages. */
132+
export function getQueueRankingPage(reader: ClickhouseReader) {
133+
return reader.query({
134+
name: "getQueueRankingPage",
135+
query: `SELECT queue_name
136+
FROM trigger_dev.queue_metrics_v1
137+
WHERE ${RANKING_WHERE}
138+
GROUP BY queue_name
139+
ORDER BY
140+
if({byQueuedOnly: UInt8} = 1, max(max_queued), max(max_queued) + max(max_running)) DESC,
141+
queue_name ASC
142+
LIMIT {limit: UInt32} OFFSET {offset: UInt32}`,
143+
params: QueueRankingParams,
144+
schema: QueueRankingRow,
145+
});
146+
}
147+
148+
const QueueRankingCountParams = QueueRankingParams.omit({
149+
byQueuedOnly: true,
150+
limit: true,
151+
offset: true,
152+
});
153+
154+
const QueueRankingCountRow = z.object({
155+
ranked: z.coerce.number(),
156+
});
157+
158+
/** How many queues have activity in the ranking window (the ranked head of the list). */
159+
export function getQueueRankingCount(reader: ClickhouseReader) {
160+
return reader.query({
161+
name: "getQueueRankingCount",
162+
query: `SELECT uniqExact(queue_name) AS ranked
163+
FROM trigger_dev.queue_metrics_v1
164+
WHERE ${RANKING_WHERE}`,
165+
params: QueueRankingCountParams,
166+
schema: QueueRankingCountRow,
167+
});
168+
}
169+
108170
// (per-queue detail series is now fetched via TRQL + fillGaps from the metric resource route)

0 commit comments

Comments
 (0)