Skip to content

Commit 3c67a0c

Browse files
committed
feat(webapp): stage fake Redis usage from the queue metrics simulator
A --usage flag stages plausible running counts in the local run-queue Redis for the seeded queues, so the list's Running column and the Allocation tab's usage bars have data without the run engine. Staged state is reconciled on every run: present with --usage, cleared without. Local Redis hosts only.
1 parent d162dcf commit 3c67a0c

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

apps/webapp/seed-queue-metrics.mts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,51 @@ async function resetEnv(ch: ClickHouse, environmentId: string) {
448448
console.log(`Reset queue metrics for environment ${environmentId}`);
449449
}
450450

451+
// Fake running counts in the run-queue Redis (Running column + allocation usage bars).
452+
// Reconciled every run: staged with --usage, cleared otherwise.
453+
async function stageRedisUsage(scenario: Scenario, ids: Ids, seed: number, clear: boolean) {
454+
const host = process.env.RUN_ENGINE_RUN_QUEUE_REDIS_HOST ?? process.env.REDIS_HOST ?? "localhost";
455+
const port = Number(
456+
process.env.RUN_ENGINE_RUN_QUEUE_REDIS_PORT ?? process.env.REDIS_PORT ?? 6379
457+
);
458+
const localHosts = new Set(["localhost", "127.0.0.1", "::1", "0.0.0.0"]);
459+
if (!localHosts.has(host)) {
460+
console.warn(`Skipping Redis usage staging on a non-local host: ${host}`);
461+
return;
462+
}
463+
try {
464+
const { createRedisClient } = await import("@internal/redis");
465+
const redis = createRedisClient({ host, port });
466+
const rng = mulberry32(seed + 1);
467+
const base = `engine:runqueue:{org:${ids.organization_id}}:proj:${ids.project_id}:env:${ids.environment_id}:queue:`;
468+
for (const [q, profile] of scenario.queues.entries()) {
469+
const key = `${base}${profile.name}:currentDequeued`;
470+
await redis.del(key);
471+
if (clear) continue;
472+
const limit = profile.limit(0);
473+
// First queue rides at/over its limit, the rest at 30-90%, sparse mostly idle.
474+
const count = profile.sparse
475+
? rng() < 0.3
476+
? 1
477+
: 0
478+
: q === 0
479+
? limit + Math.round(rng() * 2)
480+
: Math.round(limit * (0.3 + 0.6 * rng()));
481+
if (count > 0) {
482+
await redis.sadd(key, ...Array.from({ length: count }, (_v, i) => `sim_run_${i}`));
483+
}
484+
}
485+
await redis.quit();
486+
console.log(
487+
clear
488+
? "Cleared staged Redis usage."
489+
: "Staged fake running counts in Redis (Running column + allocation usage bars)."
490+
);
491+
} catch (error) {
492+
console.warn("Redis usage staging skipped:", error instanceof Error ? error.message : error);
493+
}
494+
}
495+
451496
// ---------------------------------------------------------------------------
452497
// Main
453498
// ---------------------------------------------------------------------------
@@ -530,6 +575,8 @@ Flags:
530575
--window <dur> how much history to backfill, e.g. 30m, 6h, 1d (default: 2h)
531576
--bucket <sec> seconds per simulated bucket (default: 10)
532577
--seed <n> RNG seed for reproducible data (default: 1)
578+
--usage stage fake running counts in Redis so the Running column and
579+
the Allocation tab's usage bars have data (cleared when omitted)
533580
--live after backfilling, keep appending one bucket per interval
534581
--reset clear this environment's metrics before seeding
535582
--reset-only clear and exit without seeding
@@ -625,6 +672,7 @@ async function main() {
625672

626673
const scenario = build(totalBuckets, bucketSec);
627674
await ensureTaskQueues(scenario, project.id, runtimeEnv.id);
675+
await stageRedisUsage(scenario, ids, seed, flags.usage !== "true");
628676
const rng = mulberry32(seed);
629677
const backlog = new Array(scenario.queues.length).fill(0);
630678

0 commit comments

Comments
 (0)