diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 9d497110f..f1179f189 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -319,7 +319,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s, ref BinaryCacheStore::getFSAccessor() { - return make_ref(ref(shared_from_this())); + return make_ref(ref(shared_from_this()), localNarCache); } std::shared_ptr BinaryCacheStore::getBuildLog(const Path & path) diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index f9c1c2cbe..d3b0e0bd9 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -18,6 +18,7 @@ public: const Setting compression{this, "xz", "compression", "NAR compression method ('xz', 'bzip2', or 'none')"}; const Setting writeNARListing{this, false, "write-nar-listing", "whether to write a JSON file listing the files in each NAR"}; const Setting secretKeyFile{this, "", "secret-key", "path to secret key used to sign the binary cache"}; + const Setting localNarCache{this, "", "local-nar-cache", "path to a local cache of NARs"}; private: diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc index 098151f8c..da4e30b22 100644 --- a/src/libstore/remote-fs-accessor.cc +++ b/src/libstore/remote-fs-accessor.cc @@ -3,10 +3,12 @@ namespace nix { - -RemoteFSAccessor::RemoteFSAccessor(ref store) +RemoteFSAccessor::RemoteFSAccessor(ref store, const Path & cacheDir) : store(store) + , cacheDir(cacheDir) { + if (cacheDir != "") + createDirs(cacheDir); } std::pair, Path> RemoteFSAccessor::fetch(const Path & path_) @@ -23,7 +25,21 @@ std::pair, Path> RemoteFSAccessor::fetch(const Path & path_) if (i != nars.end()) return {i->second, restPath}; StringSink sink; - store->narFromPath(storePath, sink); + + Path cacheFile = cacheDir != "" ? fmt("%s/%s.nar", cacheDir, storePathToHash(storePath)) : ""; + + try { + if (cacheFile != "") + *sink.s = nix::readFile(cacheFile); + } catch (SysError &) { } + + if (sink.s->empty()) { + store->narFromPath(storePath, sink); + + if (cacheFile != "") + /* FIXME: do this asynchronously. */ + writeFile(cacheFile, *sink.s); + } auto accessor = makeNarAccessor(sink.s); nars.emplace(storePath, accessor); diff --git a/src/libstore/remote-fs-accessor.hh b/src/libstore/remote-fs-accessor.hh index df8b7b162..d359ecc9c 100644 --- a/src/libstore/remote-fs-accessor.hh +++ b/src/libstore/remote-fs-accessor.hh @@ -12,13 +12,16 @@ class RemoteFSAccessor : public FSAccessor std::map> nars; + Path cacheDir; + std::pair, Path> fetch(const Path & path_); friend class BinaryCacheStore; public: - RemoteFSAccessor(ref store); + RemoteFSAccessor(ref store, + const /* FIXME: use std::optional */ Path & cacheDir = ""); Stat stat(const Path & path) override;