From 436fef30bc9e891708116e5fbc0df559e807b348 Mon Sep 17 00:00:00 2001 From: liu weikai Date: Wed, 30 Sep 2026 18:34:30 +0800 Subject: [PATCH] Create local publication storage only when requested --- docs/geocaching-client-runtime.md | 5 +++ .../src/geocaching/browse_runtime.cpp | 35 +++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/docs/geocaching-client-runtime.md b/docs/geocaching-client-runtime.md index edee1416..84f9d550 100644 --- a/docs/geocaching-client-runtime.md +++ b/docs/geocaching-client-runtime.md @@ -8,6 +8,11 @@ root may therefore remain absent from local views until recovery runs. The existing repair floor and archive checks still apply, and an unreadable referenced record triggers recovery rather than being silently accepted. +A read-only Downloaded session does not create the draft/publication storage +adapter. The storage worker creates it when the draft list or draft map section +is requested, or when full recovery prepares a write-capable session. Network +query and dispatch services retain their separate on-demand activation. + ## Archive a published cache Open the cache in **My caches**, save any edits, and choose **Archive cache**. diff --git a/platform/esp/arduino_common/src/geocaching/browse_runtime.cpp b/platform/esp/arduino_common/src/geocaching/browse_runtime.cpp index 577ec951..2c8b99f1 100644 --- a/platform/esp/arduino_common/src/geocaching/browse_runtime.cpp +++ b/platform/esp/arduino_common/src/geocaching/browse_runtime.cpp @@ -876,6 +876,16 @@ void startRecovery() ++epoch; } +bool ensurePublicationStore(Session& s) +{ + if (s.store) return true; + if (!s.ensureBuffers(true)) return false; + s.store.reset(::platform::memory::createPsram(s.volume, s.root, s.root_copy, s.roots[0], s.roots[1], + s.workspace_owner, s.workspace, s.frame, kFrameCapacity, + s.payload, kPayloadCapacity, s.verification, kVerificationCapacity, s.crypto)); + return s.store != nullptr; +} + void advanceStorageRecovery(Session& s) { const auto result = s.recovery->step(); @@ -917,13 +927,15 @@ void advanceStorageRecovery(Session& s) fail("Insufficient storage workspace"); return; } - s.store.reset(::platform::memory::createPsram(s.volume, s.root, s.root_copy, s.roots[0], s.roots[1], - s.workspace_owner, s.workspace, s.frame, kFrameCapacity, - s.payload, kPayloadCapacity, s.verification, kVerificationCapacity, s.crypto)); s.download_store.reset(::platform::memory::createPsram(s.volume, s.root, s.root_copy, s.roots[0], s.roots[1], s.workspace_owner, s.workspace, s.frame, kFrameCapacity, s.payload, kPayloadCapacity, s.verification, kVerificationCapacity, s.crypto)); - if (!s.store || !s.download_store || !s.workspace_owner.setPrepare(Session::prepareWorkspace, &s)) + if ((!s.local_read_only || s.draft_catalog_wanted) && !ensurePublicationStore(s)) + { + fail("Insufficient publication storage memory"); + return; + } + if (!s.download_store || !s.workspace_owner.setPrepare(Session::prepareWorkspace, &s)) { fail("Insufficient indexed storage memory"); return; @@ -1355,7 +1367,11 @@ class Facade final : public ::ui::geocaching::Source std::snprintf(out.status.data(), out.status.size(), "Updating..."); return; } - if (session && section != ::ui::geocaching::Section::Discover) session->storage_requested = true; + if (session && section != ::ui::geocaching::Section::Discover) + { + session->storage_requested = true; + if (section == ::ui::geocaching::Section::Published) session->draft_catalog_wanted = true; + } if (section == ::ui::geocaching::Section::Published && session && (session->phase == Phase::Ready || session->phase == Phase::ResumeDownloads) && session->store && !session->needsRecovery()) { session->draft_catalog_wanted = true; @@ -1994,6 +2010,11 @@ void step() return; } WorkspaceSlice workspace_slice{s}; + if (s.phase == Phase::Ready && s.draft_catalog_wanted && !ensurePublicationStore(s)) + { + next_step.store(millis() + 1000); + return; + } if (s.local_snapshot_attempted && (s.local_read_only || s.recovery)) { if (!storage::sd_card_ready() || storage::sd_external_block_owner_active()) @@ -2009,7 +2030,7 @@ void step() s.workspace_owner.release(s.detail.get()); s.detail.reset(); s.pending_detail.reset(); - s.store->releaseDraftRead(); + if (s.store) s.store->releaseDraftRead(); s.saved.reset(); if (s.draft_catalog) { @@ -2199,7 +2220,7 @@ void step() if (s.phase == Phase::Ready && s.download_start && advanceDownloadStart(s)) return; if (advanceSavedDetail(s)) return; if (s.saved && s.saved->pending() && !s.draft_catalog_wanted && !(s.phase == Phase::ResumeDownloads && s.download_port) && !downloadActive() && !publicationActive() && !draftSaveActive() && - !s.store->commitPending() && !s.needsRecovery()) + (!s.store || !s.store->commitPending()) && !s.needsRecovery()) { const auto before = s.saved->generation(); const bool worked = s.saved->advance();