From b8aa10c53555727ab8cea2e1607b9b9ee67c14da Mon Sep 17 00:00:00 2001 From: shenlei Date: Thu, 25 Jun 2026 18:57:16 +0800 Subject: [PATCH] Add diagnostic logs for total pages not updating investigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add RDEPUBBackgroundTrace.log at key decision points in the reconciliation pipeline to trace why pageMap updates get rejected: 1. refreshBookPageMapInPlace — logs when a full pageMap update is enqueued 2. evaluateTakeover — logs when keepCurrentWindow is returned due to: - jumpSession coverage ratio < 0.8 - adjacent coverage missing (hasPrev/hasNext) - renderSignature mismatch 3. evaluateFullPageMapTakeover — logs when keepCurrentWindow is returned due to: - currentSpineIndex not in candidate chapters - adjacent coverage missing 4. commitPendingPageMapUpdate — logs when keepCurrentWindow decision is applied and pending update is removed from queue Also fix unused variable warning for currentPageNumber in extendPartial case. Co-Authored-By: Claude --- ...EPUBPageMapReconciliationCoordinator.swift | 20 +++++++++++++++++++ .../RDEPUBPresentationRuntime.swift | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPageMapReconciliationCoordinator.swift b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPageMapReconciliationCoordinator.swift index 8ca00cc..03b85e8 100644 --- a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPageMapReconciliationCoordinator.swift +++ b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPageMapReconciliationCoordinator.swift @@ -52,6 +52,10 @@ final class RDEPUBPageMapReconciliationCoordinator { let coverageRatio = Double(protectedIndices.intersection(candidateIndices).count) / Double(protectedIndices.count) if coverageRatio < 0.8 { + RDEPUBBackgroundTrace.log( + "Reconciliation", + "evaluateTakeover: keepCurrentWindow — jumpSession coverageRatio=\(String(format: "%.2f", coverageRatio)) protected=\(protectedIndices.count) candidateChapters=\(candidateIndices.count)" + ) return .keepCurrentWindow } } @@ -66,6 +70,10 @@ final class RDEPUBPageMapReconciliationCoordinator { let hasPrev = candidateSegment.contains(spineIndex: currentSpineIndex - 1) let hasNext = candidateSegment.contains(spineIndex: currentSpineIndex + 1) if !hasPrev || !hasNext { + RDEPUBBackgroundTrace.log( + "Reconciliation", + "evaluateTakeover: keepCurrentWindow — adjacentCoverage missing hasPrev=\(hasPrev) hasNext=\(hasNext) currentSpine=\(currentSpineIndex)" + ) return .keepCurrentWindow } } @@ -75,6 +83,10 @@ final class RDEPUBPageMapReconciliationCoordinator { if let candidateSegment { let currentRenderSignature = context.currentRenderSignature() if candidateSegment.renderSignature != currentRenderSignature { + RDEPUBBackgroundTrace.log( + "Reconciliation", + "evaluateTakeover: keepCurrentWindow — renderSignature mismatch segment=\(candidateSegment.renderSignature) current=\(currentRenderSignature)" + ) return .keepCurrentWindow } } @@ -156,6 +168,10 @@ final class RDEPUBPageMapReconciliationCoordinator { if let currentSpineIndex { if !candidateIndices.contains(currentSpineIndex) { + RDEPUBBackgroundTrace.log( + "Reconciliation", + "evaluateFullPageMapTakeover: keepCurrentWindow — currentSpine=\(currentSpineIndex) not in candidate chapters=\(candidateIndices.count)" + ) return .keepCurrentWindow } } @@ -165,6 +181,10 @@ final class RDEPUBPageMapReconciliationCoordinator { let hasNext = candidateIndices.contains(currentSpineIndex + 1) || currentSpineIndex == lastBuildableSpineIndex if !hasPrev || !hasNext { + RDEPUBBackgroundTrace.log( + "Reconciliation", + "evaluateFullPageMapTakeover: keepCurrentWindow — adjacentCoverage missing hasPrev=\(hasPrev) hasNext=\(hasNext) currentSpine=\(currentSpineIndex)" + ) return .keepCurrentWindow } } diff --git a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPresentationRuntime.swift b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPresentationRuntime.swift index 215fd22..668cb78 100644 --- a/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPresentationRuntime.swift +++ b/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBPresentationRuntime.swift @@ -56,6 +56,10 @@ final class RDEPUBPresentationRuntime { func refreshBookPageMapInPlace(_ bookPageMap: RDEPUBBookPageMap) { navigationStateMachine.transition(to: .reconcilingFullMap) + RDEPUBBackgroundTrace.log( + "Reconciliation", + "refreshBookPageMapInPlace: enqueued reconcileFullMap chapters=\(bookPageMap.totalChapters) pages=\(bookPageMap.totalPages)" + ) enqueuePendingPageMapUpdate( RDEPUBPendingPageMapUpdate( pageMap: bookPageMap, @@ -225,6 +229,10 @@ final class RDEPUBPresentationRuntime { switch decision { case .keepCurrentWindow: + RDEPUBBackgroundTrace.log( + "Reconciliation", + "commitPendingPageMapUpdate: keepCurrentWindow — removed pending update, totalPages=\(update.pageMap.totalPages)" + ) removePendingPageMapUpdate(at: index) return false @@ -238,7 +246,7 @@ final class RDEPUBPresentationRuntime { return false } - case .extendPartial(let currentPageNumber, let currentLocation): + case .extendPartial(_, let currentLocation): removePendingPageMapUpdate(at: index) applyPageMapToLiveModel(update.pageMap, source: update.source) if let currentLocation,