diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 9d497110f621ab2b6d9686d0ebf9850c51148007..f1179f1890a04ba92ebb24548857cee3ab21e1d7 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<FSAccessor> BinaryCacheStore::getFSAccessor() { - return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this())); + return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()), localNarCache); } std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const Path & path) diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index f9c1c2cbe8a8190df8f384801f05258b746688c5..d3b0e0bd93325ed338b319e7e7bda6e2b5b8fab7 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -18,6 +18,7 @@ public: const Setting<std::string> compression{this, "xz", "compression", "NAR compression method ('xz', 'bzip2', or 'none')"}; const Setting<bool> writeNARListing{this, false, "write-nar-listing", "whether to write a JSON file listing the files in each NAR"}; const Setting<Path> secretKeyFile{this, "", "secret-key", "path to secret key used to sign the binary cache"}; + const Setting<Path> 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 098151f8c0f614b06d7cf1b1eba7aac3c32636b8..da4e30b22633457918c531557e6c6224aa011bdf 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> store) +RemoteFSAccessor::RemoteFSAccessor(ref<Store> store, const Path & cacheDir) : store(store) + , cacheDir(cacheDir) { + if (cacheDir != "") + createDirs(cacheDir); } std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_) @@ -23,7 +25,21 @@ std::pair<ref<FSAccessor>, 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 df8b7b16291e01072c5ec32b5aa7192f0d223c23..d359ecc9c8716390435602e0c71b834cceb8f694 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<Path, ref<FSAccessor>> nars; + Path cacheDir; + std::pair<ref<FSAccessor>, Path> fetch(const Path & path_); friend class BinaryCacheStore; public: - RemoteFSAccessor(ref<Store> store); + RemoteFSAccessor(ref<Store> store, + const /* FIXME: use std::optional */ Path & cacheDir = ""); Stat stat(const Path & path) override;