diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2018-09-07 17:08:43 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2018-09-07 17:08:43 +0200 |
commit | bba3f0a308cceb56bad4aa1efe13927360ae463f (patch) | |
tree | 7c778faa9df588ff0b232f37d0ca797ab8f25daa /src/libstore/http-binary-cache-store.cc | |
parent | 33c3f91885429b60cab551e761f297a640aff7d5 (diff) |
If fallback is enabled, temporarily disable substituters after a failure
Otherwise, we just keep asking the substituter for other .narinfo
files, which can take a very long time due to retries/timeouts.
Diffstat (limited to 'src/libstore/http-binary-cache-store.cc')
-rw-r--r-- | src/libstore/http-binary-cache-store.cc | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index ab524d523..8da0e2f9d 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -13,6 +13,14 @@ private: Path cacheUri; + struct State + { + bool enabled = true; + std::chrono::steady_clock::time_point disabledUntil; + }; + + Sync<State> _state; + public: HttpBinaryCacheStore( @@ -46,8 +54,33 @@ public: protected: + void maybeDisable() + { + auto state(_state.lock()); + if (state->enabled && settings.tryFallback) { + int t = 60; + printError("disabling binary cache '%s' for %s seconds", getUri(), t); + state->enabled = false; + state->disabledUntil = std::chrono::steady_clock::now() + std::chrono::seconds(t); + } + } + + void checkEnabled() + { + auto state(_state.lock()); + if (state->enabled) return; + if (std::chrono::steady_clock::now() > state->disabledUntil) { + state->enabled = true; + debug("re-enabling binary cache '%s'", getUri()); + return; + } + throw SubstituterDisabled("substituter '%s' is disabled", getUri()); + } + bool fileExists(const std::string & path) override { + checkEnabled(); + try { DownloadRequest request(cacheUri + "/" + path); request.head = true; @@ -59,6 +92,7 @@ protected: bucket is unlistable, so treat 403 as 404. */ if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden) return false; + maybeDisable(); throw; } } @@ -86,12 +120,14 @@ protected: void getFile(const std::string & path, Sink & sink) override { + checkEnabled(); auto request(makeRequest(path)); try { getDownloader()->download(std::move(request), sink); } catch (DownloadError & e) { if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden) throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache '%s'", path, getUri()); + maybeDisable(); throw; } } @@ -99,15 +135,18 @@ protected: void getFile(const std::string & path, Callback<std::shared_ptr<std::string>> callback) override { + checkEnabled(); + auto request(makeRequest(path)); getDownloader()->enqueueDownload(request, - {[callback](std::future<DownloadResult> result) { + {[callback, this](std::future<DownloadResult> result) { try { callback(result.get().data); } catch (DownloadError & e) { if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden) return callback(std::shared_ptr<std::string>()); + maybeDisable(); callback.rethrow(); } catch (...) { callback.rethrow(); |