mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 14:58:03 +03:00
6f60c48ea8
Summary: Requiring that callers ensure that ObjectFetchContext outlives the asynchronous result is a burden and a memory-safety risk. Without Rust's borrow checker, we can't feel confident this is safe under all error and timeout conditions. It also requires we use folly::collectAll and collectAllSafe, which means that an error during fanout has to wait until the fanout completes before we can report the error to our caller. Moreover, tying the ObjectFetchContext's lifetime to the FUSE/NFS/Thrift/etc. request's lifetime gives us incorrect statistics about how long the request takes. I consider this an API design mistake (on my part). Correct the situation by decoupling ObjectFetchContext from RequestContext, and begin reference-counting ObjectFetchContext. This does increase the number of atomic RMW operations, but we can alleviate those where they matter by manually checking *Future::isReady() before calling .then*. Reviewed By: xavierd Differential Revision: D40744706 fbshipit-source-id: 5baf654f6d65790ed0cafb45c0bc7f2aaa8ecec2
102 lines
3.2 KiB
C++
102 lines
3.2 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "eden/fs/store/BackingStore.h"
|
|
|
|
namespace facebook::eden {
|
|
|
|
class BackingStore;
|
|
class LocalStore;
|
|
class EdenStats;
|
|
|
|
/**
|
|
* Implementation of a BackingStore that caches the returned data from another
|
|
* BackingStore onto the LocalStore.
|
|
*
|
|
* Reads will first attempt to read from the LocalStore, and will only read
|
|
* from the underlying BackingStore if the data wasn't found in the LocalStore.
|
|
*
|
|
* This should be used for BackingStores that either do not have local caching
|
|
* builtin, or when reading from this cache is significantly slower than
|
|
* reading from the LocalStore.
|
|
*/
|
|
class LocalStoreCachedBackingStore : public BackingStore {
|
|
public:
|
|
LocalStoreCachedBackingStore(
|
|
std::shared_ptr<BackingStore> backingStore,
|
|
std::shared_ptr<LocalStore> localStore,
|
|
std::shared_ptr<EdenStats> stats);
|
|
~LocalStoreCachedBackingStore() override;
|
|
|
|
ObjectComparison compareObjectsById(const ObjectId& one, const ObjectId& two)
|
|
override;
|
|
|
|
ImmediateFuture<std::unique_ptr<Tree>> getRootTree(
|
|
const RootId& rootId,
|
|
const ObjectFetchContextPtr& context) override;
|
|
|
|
ImmediateFuture<std::unique_ptr<TreeEntry>> getTreeEntryForObjectId(
|
|
const ObjectId& objectId,
|
|
TreeEntryType treeEntryType,
|
|
const ObjectFetchContextPtr& context) override;
|
|
folly::SemiFuture<GetTreeResult> getTree(
|
|
const ObjectId& id,
|
|
const ObjectFetchContextPtr& context) override;
|
|
folly::SemiFuture<GetBlobResult> getBlob(
|
|
const ObjectId& id,
|
|
const ObjectFetchContextPtr& context) override;
|
|
|
|
std::unique_ptr<BlobMetadata> getLocalBlobMetadata(
|
|
const ObjectId& id,
|
|
const ObjectFetchContextPtr& context) override;
|
|
|
|
FOLLY_NODISCARD folly::SemiFuture<folly::Unit> prefetchBlobs(
|
|
ObjectIdRange ids,
|
|
const ObjectFetchContextPtr& context) override;
|
|
|
|
void periodicManagementTask() override;
|
|
|
|
void startRecordingFetch() override;
|
|
std::unordered_set<std::string> stopRecordingFetch() override;
|
|
|
|
folly::SemiFuture<folly::Unit> importManifestForRoot(
|
|
const RootId& rootId,
|
|
const Hash20& manifest) override;
|
|
|
|
RootId parseRootId(folly::StringPiece rootId) override;
|
|
std::string renderRootId(const RootId& rootId) override;
|
|
ObjectId parseObjectId(folly::StringPiece objectId) override;
|
|
std::string renderObjectId(const ObjectId& objectId) override;
|
|
|
|
std::optional<folly::StringPiece> getRepoName() override;
|
|
|
|
/**
|
|
* Get the underlying BackingStore. This should only be used for operations
|
|
* that need to be made directly on the BackingStore, like getting a TraceBus
|
|
*/
|
|
const std::shared_ptr<BackingStore>& getBackingStore() {
|
|
return backingStore_;
|
|
}
|
|
|
|
// TODO(T119221752): Implement for all BackingStore subclasses
|
|
int64_t dropAllPendingRequestsFromQueue() override {
|
|
XLOG(
|
|
WARN,
|
|
"dropAllPendingRequestsFromQueue() is not implemented for LocalStoreCachedBackingStore");
|
|
return 0;
|
|
}
|
|
|
|
private:
|
|
std::shared_ptr<BackingStore> backingStore_;
|
|
std::shared_ptr<LocalStore> localStore_;
|
|
std::shared_ptr<EdenStats> stats_;
|
|
};
|
|
|
|
} // namespace facebook::eden
|