Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/libstore/binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "nix/util/callback.hh"
#include "nix/util/signals.hh"
#include "nix/util/archive.hh"
#include "nix/store/nar-cache.hh"

#include <chrono>
#include <future>
Expand All @@ -26,6 +27,7 @@ namespace nix {

BinaryCacheStore::BinaryCacheStore(Config & config)
: config{config}
, narCache{config.localNarCache.get() ? std::make_shared<NarCache>(*config.localNarCache.get()) : nullptr}
{
if (config.secretKeyFile != "")
signers.push_back(std::make_unique<LocalSigner>(SecretKey{readFile(config.secretKeyFile)}));
Expand Down Expand Up @@ -552,7 +554,7 @@ void BinaryCacheStore::registerDrvOutput(const Realisation & info)

ref<RemoteFSAccessor> BinaryCacheStore::getRemoteFSAccessor(bool requireValidPath)
{
return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()), requireValidPath, config.localNarCache);
return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()), requireValidPath, narCache);
}

ref<SourceAccessor> BinaryCacheStore::getFSAccessor(bool requireValidPath)
Expand Down
3 changes: 3 additions & 0 deletions src/libstore/include/nix/store/binary-cache-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace nix {

struct NarInfo;
class NarCache;
class RemoteFSAccessor;

struct BinaryCacheStoreConfig : virtual StoreConfig
Expand Down Expand Up @@ -89,6 +90,8 @@ protected:

constexpr const static std::string cacheInfoFile = "nix-cache-info";

std::shared_ptr<NarCache> narCache;

BinaryCacheStore(Config &);

/**
Expand Down
1 change: 1 addition & 0 deletions src/libstore/include/nix/store/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ headers = [ config_pub_h ] + files(
'machines.hh',
'make-content-addressed.hh',
'names.hh',
'nar-cache.hh',
'nar-info-disk-cache.hh',
'nar-info.hh',
'outputs-spec.hh',
Expand Down
33 changes: 33 additions & 0 deletions src/libstore/include/nix/store/nar-cache.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "nix/util/hash.hh"
#include "nix/util/nar-accessor.hh"

#include <filesystem>

namespace nix {

class NarCache
{
const std::filesystem::path cacheDir;

std::filesystem::path makeCacheFile(const Hash & narHash, const std::string & ext);

public:

NarCache(std::filesystem::path cacheDir);

void upsertNar(const Hash & narHash, Source & source);

void upsertNarListing(const Hash & narHash, std::string_view narListingData);

// FIXME: use a sink.
std::optional<std::string> getNar(const Hash & narHash);

// FIXME: use a sink.
GetNarBytes getNarBytes(const Hash & narHash);

std::optional<std::string> getNarListing(const Hash & narHash);
};

} // namespace nix
7 changes: 4 additions & 3 deletions src/libstore/include/nix/store/remote-fs-accessor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace nix {

struct NarCache;

class RemoteFSAccessor : public SourceAccessor
{
ref<Store> store;
Expand All @@ -25,7 +27,7 @@ class RemoteFSAccessor : public SourceAccessor

bool requireValidPath;

std::optional<std::filesystem::path> cacheDir;
std::shared_ptr<NarCache> narCache;

std::pair<ref<SourceAccessor>, CanonPath> fetch(const CanonPath & path);

Expand All @@ -38,8 +40,7 @@ public:
*/
std::shared_ptr<SourceAccessor> accessObject(const StorePath & path);

RemoteFSAccessor(
ref<Store> store, bool requireValidPath = true, std::optional<std::filesystem::path> cacheDir = {});
RemoteFSAccessor(ref<Store> store, bool requireValidPath = true, std::shared_ptr<NarCache> narCache = {});

std::optional<Stat> maybeLstat(const CanonPath & path) override;

Expand Down
1 change: 1 addition & 0 deletions src/libstore/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ sources = files(
'make-content-addressed.cc',
'misc.cc',
'names.cc',
'nar-cache.cc',
'nar-info-disk-cache.cc',
'nar-info.cc',
'optimise-store.cc',
Expand Down
64 changes: 64 additions & 0 deletions src/libstore/nar-cache.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "nix/store/nar-cache.hh"
#include "nix/util/file-system.hh"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

namespace nix {

NarCache::NarCache(std::filesystem::path cacheDir_)
: cacheDir(std::move(cacheDir_))
{
assert(!cacheDir.empty());
createDirs(cacheDir);
}

std::filesystem::path NarCache::makeCacheFile(const Hash & narHash, const std::string & ext)
{
return (cacheDir / narHash.to_string(HashFormat::Nix32, false)) + "." + ext;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I think this will fail to build on MinGW. See ccdd1f1

}

void NarCache::upsertNar(const Hash & narHash, Source & source)
{
try {
/* FIXME: do this asynchronously. */
writeFile(makeCacheFile(narHash, "nar"), source);
} catch (SystemError &) {
ignoreExceptionExceptInterrupt();
}
}

void NarCache::upsertNarListing(const Hash & narHash, std::string_view narListingData)
{
try {
writeFile(makeCacheFile(narHash, "ls"), narListingData);
} catch (SystemError &) {
ignoreExceptionExceptInterrupt();
}
}

std::optional<std::string> NarCache::getNar(const Hash & narHash)
{
try {
return nix::readFile(makeCacheFile(narHash, "nar"));
} catch (SystemError &) {
return std::nullopt;
}
}

GetNarBytes NarCache::getNarBytes(const Hash & narHash)
{
return seekableGetNarBytes(makeCacheFile(narHash, "nar"));
}

std::optional<std::string> NarCache::getNarListing(const Hash & narHash)
{
try {
return nix::readFile(makeCacheFile(narHash, "ls"));
} catch (SystemError &) {
return std::nullopt;
}
}

} // namespace nix
59 changes: 13 additions & 46 deletions src/libstore/remote-fs-accessor.cc
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
#include <nlohmann/json.hpp>
#include "nix/store/remote-fs-accessor.hh"
#include "nix/util/nar-accessor.hh"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "nix/store/nar-cache.hh"

namespace nix {

RemoteFSAccessor::RemoteFSAccessor(
ref<Store> store, bool requireValidPath, std::optional<std::filesystem::path> cacheDir_)
RemoteFSAccessor::RemoteFSAccessor(ref<Store> store, bool requireValidPath, std::shared_ptr<NarCache> narCache)
: store(store)
, requireValidPath(requireValidPath)
, cacheDir(std::move(cacheDir_))
, narCache(std::move(narCache))
{
if (cacheDir)
createDirs(*cacheDir);
}

std::pair<ref<SourceAccessor>, CanonPath> RemoteFSAccessor::fetch(const CanonPath & path)
Expand Down Expand Up @@ -47,48 +40,22 @@ std::shared_ptr<SourceAccessor> RemoteFSAccessor::accessObject(const StorePath &
return std::move(sink.s);
};

if (cacheDir) {
auto makeCacheFile = [&](const std::string & ext) {
auto res = *cacheDir / info->narHash.to_string(HashFormat::Nix32, false);
res += ".";
res += ext;
return res;
};

auto cacheFile = makeCacheFile("nar");
auto listingFile = makeCacheFile("ls");

if (nix::pathExists(cacheFile)) {
try {
return cacheAccessor(makeLazyNarAccessor(
nlohmann::json::parse(nix::readFile(listingFile)).template get<NarListing>(),
seekableGetNarBytes(cacheFile)));
} catch (SystemError &) {
}

try {
return cacheAccessor(makeNarAccessor(nix::readFile(cacheFile)));
} catch (SystemError &) {
}
}
if (narCache) {
if (auto listingData = narCache->getNarListing(info->narHash))
return cacheAccessor(makeLazyNarAccessor(
nlohmann::json::parse(*listingData).template get<NarListing>(), narCache->getNarBytes(info->narHash)));

if (auto nar = narCache->getNar(info->narHash))
return cacheAccessor(makeNarAccessor(std::move(*nar)));

auto nar = getNar();

try {
/* FIXME: do this asynchronously. */
writeFile(cacheFile, nar);
} catch (...) {
ignoreExceptionExceptInterrupt();
}
StringSource source{nar};
narCache->upsertNar(info->narHash, source);

auto narAccessor = makeNarAccessor(std::move(nar));

try {
nlohmann::json j = narAccessor->getListing();
writeFile(listingFile, j.dump());
} catch (...) {
ignoreExceptionExceptInterrupt();
}
narCache->upsertNarListing(info->narHash, nlohmann::json(narAccessor->getListing()).dump());

return cacheAccessor(narAccessor);
}
Expand Down
Loading