[Bug][Backend][MinIO] Cutover blocker: UploadOrchestrator reads BookPageImage.AbsoluteImagePath with raw File.Exists — dropping the /app/ebooks bind silently kills book image descriptions (epic #413, blocks #528/#529) #598
Reference in New Issue
Block a user
Found while verifying #528. Not a live bug today — a landmine that detonates on cutover day, which is exactly when it is most expensive.
The problem
SpikerSoft.Data/Mongos/BookPageImage.cs:48persists an absolute filesystem path into Mongo:Its consumers read it straight off the filesystem, bypassing
IObjectStoreentirely:SpikerSoft.EventHandlers.UploadCoordinator/Services/UploadOrchestrator.cs:891—if (File.Exists(image.AbsoluteImagePath))UploadOrchestrator.cs:814— passes it asimagePathinto the image-description pipelineUploadOrchestrator.cs:749— error messageWriters:
MetadataExtractor/Services/MetadataExtractionService.cs:499and:882.Why it matters
Epic #413's goal is to remove the
/mnt/fusionio/spikersoft/ebooks:/app/ebooksbind. The moment that bind is gone:File.Exists("/app/ebooks/...")returns false, not an error.This is the same silent-degradation class as #553 and #557: the failure mode is a false negative, not an exception, so it will not show up as a red service — only as books that mysteriously have no image descriptions.
The #528 media-serving middleware does not cover this. That middleware maps URL prefixes (
/ebooks/...) onto bucket keys;AbsoluteImagePathis a worker-side filesystem read on a completely different code path.Fix
Route the
AbsoluteImagePathconsumers throughIObjectStore, mapping path→key with the sharedObjectKeys.TryMapKey(path, pathPrefix: "/app/ebooks")shim (#533) — the same trick every other migrated service already uses. The ebooks bucket +IObjectStoreare already wired into FileMovement/MetadataExtractor, so this is plumbing, not new infrastructure.Alternatively, stop persisting absolute paths at all and store the object key, deriving the local path only where a local file is genuinely required.
Acceptance
File.Exists/File.Openagainst/app/ebooksanywhere in UploadCoordinator.Blocks: the ebooks-bind removal in #528 / the #529 coordinated cutover. Should be fixed before Phase 2, not discovered during it.
Resolved in spikersoft-backend PR #297 (merged to
masteras bc55a9ff).UploadOrchestratorno longer answers image existence with a bareFile.Existson/app/ebooks/...— it goes throughIBookImageLocator, which is filesystem-first and falls back to theebooksbucket (the same contract the Python image-description worker already uses on the bind-less 4090 lane). Removing the ebooks bind will no longer fail healthy books as 'corrupt'. 19/19 tests,UnitTests.slnfclean.Ops prerequisite still required before enabling (
Storage__UseS3already true for other reasons): theuploads-svckey must gain read onebooks(runbook Phase 0 step 2), or lookups 403 and books fail as corrupt — the exact bug this prevents. Closing the code work; the key-policy step is tracked under #529 Phase 0.