mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
067abe2d55
Summary: This adds counters for memory and disk counts in addition to import count so that we can understand cache hit rates during local investigation or output this in ActivityRecorder. Reviewed By: genevievehelsel Differential Revision: D29805637 fbshipit-source-id: 34261f91c33d6bd4bcb4b85b17d2e68360410896
108 lines
3.1 KiB
C++
108 lines
3.1 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <folly/futures/Future.h>
|
|
#include <atomic>
|
|
#include <utility>
|
|
|
|
#include "eden/fs/store/ImportPriority.h"
|
|
#include "eden/fs/store/ObjectFetchContext.h"
|
|
#include "eden/fs/telemetry/EdenStats.h"
|
|
#include "eden/fs/telemetry/RequestMetricsScope.h"
|
|
#include "eden/fs/utils/ProcessAccessLog.h"
|
|
|
|
namespace facebook::eden {
|
|
|
|
class RequestContext : public ObjectFetchContext {
|
|
// Needed to track stats
|
|
std::chrono::time_point<std::chrono::steady_clock> startTime_;
|
|
ChannelThreadStats::StatPtr latencyStat_{nullptr};
|
|
EdenStats* stats_{nullptr};
|
|
RequestMetricsScope requestMetricsScope_;
|
|
std::shared_ptr<RequestMetricsScope::LockedRequestWatchList>
|
|
channelThreadLocalStats_;
|
|
ProcessAccessLog& pal_;
|
|
|
|
struct EdenTopStats {
|
|
public:
|
|
Origin getFetchOrigin() {
|
|
return fetchOrigin_.load(std::memory_order_relaxed);
|
|
}
|
|
void setFetchOrigin(Origin origin) {
|
|
fetchOrigin_.store(origin, std::memory_order_relaxed);
|
|
}
|
|
std::chrono::nanoseconds fuseDuration{0};
|
|
|
|
private:
|
|
std::atomic<Origin> fetchOrigin_{Origin::NotFetched};
|
|
} edenTopStats_;
|
|
|
|
/**
|
|
* Normally, one requestData is created for only one fetch request,
|
|
* so priority will only be accessed by one thread, but that is
|
|
* not strictly guaranteed. Atomic is used here because there
|
|
* might be rare cases where multiple threads access priority_
|
|
* at the same time.
|
|
*/
|
|
std::atomic<ImportPriority> priority_{
|
|
ImportPriority(ImportPriorityKind::High)};
|
|
|
|
public:
|
|
RequestContext(const RequestContext&) = delete;
|
|
RequestContext& operator=(const RequestContext&) = delete;
|
|
RequestContext(RequestContext&&) = delete;
|
|
RequestContext& operator=(RequestContext&&) = delete;
|
|
|
|
explicit RequestContext(ProcessAccessLog& pal) : pal_(pal) {}
|
|
|
|
/**
|
|
* Override of `ObjectFetchContext`
|
|
*
|
|
* Unlike other RequestContext function, this may be called concurrently by
|
|
* arbitrary threads.
|
|
*/
|
|
void didFetch(ObjectType /*type*/, const Hash& /*hash*/, Origin origin)
|
|
override {
|
|
edenTopStats_.setFetchOrigin(origin);
|
|
}
|
|
|
|
// Override of `getPriority`
|
|
ImportPriority getPriority() const override {
|
|
return priority_;
|
|
}
|
|
|
|
// Override of `deprioritize`
|
|
virtual void deprioritize(uint64_t delta) override {
|
|
ImportPriority prev = priority_.load();
|
|
priority_.compare_exchange_strong(prev, prev.getDeprioritized(delta));
|
|
if (getClientPid().has_value()) {
|
|
XLOG(DBG7) << "priority for " << getClientPid().value()
|
|
<< " has changed to: " << priority_.load().value();
|
|
}
|
|
}
|
|
|
|
// Override of `ObjectFetchContext`
|
|
Cause getCause() const override {
|
|
return ObjectFetchContext::Cause::Fs;
|
|
}
|
|
|
|
void startRequest(
|
|
EdenStats* stats,
|
|
ChannelThreadStats::StatPtr stat,
|
|
std::shared_ptr<RequestMetricsScope::LockedRequestWatchList>&
|
|
requestWatches);
|
|
void finishRequest();
|
|
|
|
EdenTopStats& getEdenTopStats() {
|
|
return edenTopStats_;
|
|
}
|
|
};
|
|
|
|
} // namespace facebook::eden
|