Bläddra i källkod

fix(investment): keep catalog failures closed

y9522 2 veckor sedan
förälder
incheckning
93806259b5

+ 18 - 2
Sunrise/src/state/build_data/items/catalysts/exotic_catalyst_build_data_runtime.cpp

@@ -45,6 +45,19 @@ valid_publication(const items::catalysts::Source& source,
                bound, items::catalysts::generated_facts(), definitions);
                bound, items::catalysts::generated_facts(), definitions);
 }
 }
 
 
+/**
+ * Records the last whole-catalog derivation result for cache policy.
+ * @param error None after a safe derivation, or its exact failure reason.
+ */
+void record_derivation_error(items::catalysts::Error error) noexcept {
+    runtime::persistence::Context& state = runtime::persistence::context();
+    AcquireSRWLockExclusive(&state.lock);
+    if (state.enabled) {
+        state.catalystError = error;
+    }
+    ReleaseSRWLockExclusive(&state.lock);
+}
+
 } // namespace
 } // namespace
 
 
 bool exotic_catalysts_ready() noexcept {
 bool exotic_catalysts_ready() noexcept {
@@ -61,10 +74,13 @@ bool derive_exotic_catalysts(const items::catalysts::Source& source,
         report = {};
         report = {};
         report.error = items::catalysts::Error::unsupportedBuild;
         report.error = items::catalysts::Error::unsupportedBuild;
         report.unsupported = 1;
         report.unsupported = 1;
+        record_derivation_error(report.error);
         return false;
         return false;
     }
     }
-    return items::catalysts::derive(
-        bound, items::catalysts::generated_facts(), output, count, report);
+    const bool derived =
+        items::catalysts::derive(bound, items::catalysts::generated_facts(), output, count, report);
+    record_derivation_error(derived ? items::catalysts::Error::none : report.error);
+    return derived;
 }
 }
 
 
 bool publish_exotic_catalysts(const items::catalysts::Source& source,
 bool publish_exotic_catalysts(const items::catalysts::Source& source,

+ 5 - 1
Sunrise/src/state/build_data/runtime.h

@@ -587,7 +587,11 @@ publish_vendor_catalog(std::span<const vendors::IndexEntry> index,
 [[nodiscard]] bool find_vendor_definition(std::uint32_t definitionHash,
 [[nodiscard]] bool find_vendor_definition(std::uint32_t definitionHash,
                                           vendors::Definition& definition) noexcept;
                                           vendors::Definition& definition) noexcept;
 
 
-/** @return True only when every domain is ready and any needed cache write succeeds. */
+/**
+ * @return True when required domains are ready and either the full cache write succeeds or the
+
+ * * optional catalyst catalog rejects an unsupported build without writing an incomplete cache.
+ */
 [[nodiscard]] bool persist() noexcept;
 [[nodiscard]] bool persist() noexcept;
 
 
 } // namespace sunrise::state::build_data
 } // namespace sunrise::state::build_data

+ 3 - 1
Sunrise/src/state/build_data/runtime/persistence/build_data_persistence.cpp

@@ -261,6 +261,7 @@ void clear_locked(Context& state) noexcept {
     state.cacheDirectory = {};
     state.cacheDirectory = {};
     state.cachePath = {};
     state.cachePath = {};
     state.buildIdentity = {};
     state.buildIdentity = {};
+    state.catalystError = items::catalysts::Error::none;
     state.enabled = false;
     state.enabled = false;
     state.persisted = false;
     state.persisted = false;
     state.replaceStaleCache = false;
     state.replaceStaleCache = false;
@@ -359,7 +360,8 @@ bool persist() noexcept {
     AcquireSRWLockExclusive(&state.lock);
     AcquireSRWLockExclusive(&state.lock);
     const bool requiredReady = runtime::persistence::required_domains_ready();
     const bool requiredReady = runtime::persistence::required_domains_ready();
     bool result = false;
     bool result = false;
-    if (requiredReady && !exotic_catalysts_ready()) {
+    if (requiredReady && !exotic_catalysts_ready()
+        && state.catalystError == items::catalysts::Error::unsupportedBuild) {
         // Catalyst facts are build-pinned. A rejected build must not keep the refresh worker
         // Catalyst facts are build-pinned. A rejected build must not keep the refresh worker
         // active or put an incomplete catalog on disk. Other extracted domains stay usable.
         // active or put an incomplete catalog on disk. Other extracted domains stay usable.
         runtime::persistence::release_scratch_locked(state);
         runtime::persistence::release_scratch_locked(state);

+ 2 - 0
Sunrise/src/state/build_data/runtime/persistence/build_data_persistence.h

@@ -58,6 +58,8 @@ struct Context {
     core::path::Buffer cacheDirectory;
     core::path::Buffer cacheDirectory;
     core::path::Buffer cachePath;
     core::path::Buffer cachePath;
     BuildIdentity buildIdentity{};
     BuildIdentity buildIdentity{};
+    /** Last catalyst derivation error for this build. */
+    items::catalysts::Error catalystError{items::catalysts::Error::none};
     bool enabled{};
     bool enabled{};
     bool persisted{};
     bool persisted{};
     bool replaceStaleCache{};
     bool replaceStaleCache{};