Skip to content

Commit 7c45233

Browse files
committed
fix: drop diluted-rate fallback in osspckgs monitor merge ETA
Signed-off-by: Uroš Marolt <uros@marolt.me>
1 parent 2bec760 commit 7c45233

1 file changed

Lines changed: 17 additions & 24 deletions

File tree

services/apps/packages_worker/src/scripts/monitorOsspckgs.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -710,38 +710,31 @@ function updateChunkHistory(job: any, now: number) {
710710
}
711711

712712
// ETA to finish merging the current staging chunk.
713-
// Uses historical merge rate from completed chunks when available; falls back to overall job
714-
// throughput (includes loading time, so slightly conservative) when none observed yet.
713+
// Uses historical merge rate from completed chunks only. With no chunk history yet
714+
// (e.g. monitor started mid-merge) there is no trustworthy throughput signal — pgRows/elapsed
715+
// is diluted by the export+download phases where pgRows is ~0 and mis-projects by ~30x — so we
716+
// show "—" until a chunk boundary is observed rather than print a wildly wrong number.
715717
// eslint-disable-next-line @typescript-eslint/no-explicit-any
716718
function computeChunkEta(job: any) {
717719
if (job.status !== 'merging') return null
718720
const stagingRows = Number(job.row_count_staging) || 0
719721
if (!stagingRows) return null
720722
const hist = chunkMergeHistory.get(job.id)
721723
if (!hist || hist.mergeStart == null) return null
722-
723-
let rateRowsPerMs: number
724-
if (hist.completedChunks.length > 0) {
725-
// Exponential recency weighting: chunk i gets weight 2^i (oldest=0, newest=n-1).
726-
// Most recent chunk contributes ~50% of the rate; history stabilises it.
727-
const chunks = hist.completedChunks
728-
let weightedRate = 0,
729-
totalWeight = 0
730-
for (let i = 0; i < chunks.length; i++) {
731-
const w = Math.pow(2, i)
732-
weightedRate += (chunks[i].stagingRows / chunks[i].durationMs) * w
733-
totalWeight += w
734-
}
735-
if (totalWeight === 0) return null
736-
rateRowsPerMs = weightedRate / totalWeight
737-
} else {
738-
// No completed chunks observed — derive rate from overall job progress (conservative: includes loading)
739-
const pgRows = Number(job.row_count_pg) || 0
740-
if (!pgRows || !job.started_at) return null
741-
const jobElapsedMs = Date.now() - new Date(job.started_at).getTime()
742-
if (jobElapsedMs < 10000) return null
743-
rateRowsPerMs = pgRows / jobElapsedMs
724+
if (hist.completedChunks.length === 0) return null
725+
726+
// Exponential recency weighting: chunk i gets weight 2^i (oldest=0, newest=n-1).
727+
// Most recent chunk contributes ~50% of the rate; history stabilises it.
728+
const chunks = hist.completedChunks
729+
let weightedRate = 0,
730+
totalWeight = 0
731+
for (let i = 0; i < chunks.length; i++) {
732+
const w = Math.pow(2, i)
733+
weightedRate += (chunks[i].stagingRows / chunks[i].durationMs) * w
734+
totalWeight += w
744735
}
736+
if (totalWeight === 0) return null
737+
const rateRowsPerMs = weightedRate / totalWeight
745738

746739
const estimatedDurationMs = stagingRows / rateRowsPerMs
747740
const elapsedMs = Date.now() - hist.mergeStart

0 commit comments

Comments
 (0)