Loading debian/changelog +8 −0 Original line number Diff line number Diff line mediadb (20260426+1) unstable; urgency=medium * Fix preview 30s stall: bulk_prefetch() now uses chunked range reads (read_media_data_range) instead of read_media_data(), avoiding the retrieve_range retry backoff loop that blocks preview generation -- Jan Koester <jan.koester@tuxist.de> Sat, 26 Apr 2026 12:00:00 +0200 mediadb (20260426) unstable; urgency=high * Fix cluster data loss: skip orphan cleanup in vacuum_all_stores() Loading src/preview.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -57,13 +57,26 @@ struct PrefetchBuffer { } } // Fetch the entire file in a single cluster round-trip. // Call once after setting up db/media_id/total_size. // Fetch the entire file using chunked range reads (same fast path // as /raw). The old read_media_data() → retrieve() path retries // each failing stripe with exponential backoff (~30 s total), while // read_media_data_range() → retrieve_range() fails immediately per // stripe — avoiding the long stall that blocks preview generation. void bulk_prefetch() { if (total_size == 0 || total_size > BULK_FETCH_LIMIT) return; bulk_data_ = db->read_media_data(media_id); static constexpr std::uint64_t CHUNK = 4 * 1024 * 1024; // 4 MB bulk_data_.reserve(static_cast<std::size_t>(total_size)); for (std::uint64_t off = 0; off < total_size; off += CHUNK) { std::uint64_t len = std::min<std::uint64_t>(CHUNK, total_size - off); auto chunk = db->read_media_data_range(media_id, off, len); if (chunk.empty()) { bulk_data_.clear(); return; } bulk_data_.insert(bulk_data_.end(), chunk.begin(), chunk.end()); } if (!bulk_data_.empty()) { total_size = bulk_data_.size(); // align with actual bytes total_size = bulk_data_.size(); } } Loading Loading
debian/changelog +8 −0 Original line number Diff line number Diff line mediadb (20260426+1) unstable; urgency=medium * Fix preview 30s stall: bulk_prefetch() now uses chunked range reads (read_media_data_range) instead of read_media_data(), avoiding the retrieve_range retry backoff loop that blocks preview generation -- Jan Koester <jan.koester@tuxist.de> Sat, 26 Apr 2026 12:00:00 +0200 mediadb (20260426) unstable; urgency=high * Fix cluster data loss: skip orphan cleanup in vacuum_all_stores() Loading
src/preview.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -57,13 +57,26 @@ struct PrefetchBuffer { } } // Fetch the entire file in a single cluster round-trip. // Call once after setting up db/media_id/total_size. // Fetch the entire file using chunked range reads (same fast path // as /raw). The old read_media_data() → retrieve() path retries // each failing stripe with exponential backoff (~30 s total), while // read_media_data_range() → retrieve_range() fails immediately per // stripe — avoiding the long stall that blocks preview generation. void bulk_prefetch() { if (total_size == 0 || total_size > BULK_FETCH_LIMIT) return; bulk_data_ = db->read_media_data(media_id); static constexpr std::uint64_t CHUNK = 4 * 1024 * 1024; // 4 MB bulk_data_.reserve(static_cast<std::size_t>(total_size)); for (std::uint64_t off = 0; off < total_size; off += CHUNK) { std::uint64_t len = std::min<std::uint64_t>(CHUNK, total_size - off); auto chunk = db->read_media_data_range(media_id, off, len); if (chunk.empty()) { bulk_data_.clear(); return; } bulk_data_.insert(bulk_data_.end(), chunk.begin(), chunk.end()); } if (!bulk_data_.empty()) { total_size = bulk_data_.size(); // align with actual bytes total_size = bulk_data_.size(); } } Loading