better sync progress reporting

This commit is contained in:
olcxja 2026-10-06 08:11:31 +02:00
commit d4996988d9
3 changed files with 34 additions and 16 deletions

View file

@ -915,14 +915,15 @@ async function handlePlan(state, session, url, req, res, hooks) {
let inFlight = 0
const settleOldest = () => Promise.race(jobs.splice(0, 1))
await readNdjson(req, async entry => {
if (!inlineSame(entry)) return
// the sender announces its unit total before hashing starts (a control
// record, no path): it carries the compare bar's width, so it must be
// read before the entry filter drops it
if (entry.unitBytes != null) {
// the sender announces its unit total before hashing starts; it can
// arrive after early compares (dirs/links), so it just overwrites
unitTotalBytes = Number(entry.unitBytes) || 0
session.barTotal = unitTotalBytes || 1
return
}
if (!inlineSame(entry)) return
entries.push(entry)
if (!withinRoots(entry.path, owned)) return
if (forced) {
@ -968,14 +969,16 @@ async function handlePlan(state, session, url, req, res, hooks) {
// this unit's files/bytes, reported as they arrive
session.planned += upload.length
session.plannedBytes += uploadBytes
// the bar restarts for the copy phase
session.unitWritten = 0
session.barTotal = uploadBytes
session.barBytes = 0
// the unit's label is announced up front, so file events can name it
session.unitLabel = label
sendJson(res, 200, { ok: true, upload, same, entries: paths.size })
// the compare is finished: report it full, then reset for the copy phase
// (the first byte that arrives emits the new bar)
session.barTotal = unitTotalBytes || session.barTotal || 1
session.barBytes = session.barTotal
announce({ unit: label }, true)
session.unitWritten = 0
session.unitLabel = label // named up front, so file events can label it
session.barBytes = 0
session.barTotal = uploadBytes
sendJson(res, 200, { ok: true, upload, same, entries: paths.size })
}
// One PUT, one file. The sender declares a content-length up front; if the
@ -1095,6 +1098,9 @@ async function handleApply(session, req, res, hooks) {
function handleEnd(state, session, res, hooks) {
state.tokens.delete(session.token)
if (state.session && state.session.token === session.token) state.session = null
// a finished sync leaves a finished bar, even one that moved no files
session.barTotal = session.barTotal || 1
session.barBytes = session.barTotal
sendJson(res, 200, { ok: true })
emitReceive(hooks, session, 'done', { deleted: session.deleted || 0 })
}