Skip to content

Commit

Permalink
watchman: cache Mercurial::getFilesChangedSinceMergeBaseWith results
Browse files Browse the repository at this point in the history
Summary:
This commit uses the same technique as we use for the mergeBase
cache in the prior commit to produce a cache key, so that we'll effectively
invalidate the results when the dirstate is changed.

This provides both caching and thundering herd protection when multiple
clients are performing SCM aware queries concurrently.  We've had some
issues in the past where we'd OOM a cgroup slice under the combined
memory pressure of the the concurrent `hg` processes.

Reviewed By: chadaustin

Differential Revision: D22582273

fbshipit-source-id: 19f6a81b1c18831878f4a7aab4ec4a1ef82033da
  • Loading branch information
wez authored and facebook-github-bot committed Aug 28, 2020
1 parent e2e877c commit 5713a8d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
50 changes: 34 additions & 16 deletions scm/Mercurial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@ ChildProcess::Options Mercurial::makeHgOptions(w_string requestId) const {
Mercurial::Mercurial(w_string_piece rootPath, w_string_piece scmRoot)
: SCM(rootPath, scmRoot),
dirStatePath_(to<std::string>(getSCMRoot(), "/.hg/dirstate")),
mergeBases_(Configuration(), "scm_hg_mergebase", 32, 10) {}
mergeBases_(Configuration(), "scm_hg_mergebase", 32, 10),
filesChangedSinceMergeBaseWith_(
Configuration(),
"scm_hg_files_since_mergebase",
32,
10) {}

struct timespec Mercurial::getDirStateMtime() const {
try {
Expand Down Expand Up @@ -165,22 +170,35 @@ w_string Mercurial::mergeBaseWith(w_string_piece commitId, w_string requestId)
std::vector<w_string> Mercurial::getFilesChangedSinceMergeBaseWith(
w_string_piece commitId,
w_string requestId) const {
// The "" argument at the end causes paths to be printed out relative to the
// cwd (set to root path above).
auto result = runMercurial(
{hgExecutablePath(),
"--traceback",
"status",
"-n",
"--rev",
commitId,
""},
makeHgOptions(requestId),
"query for files changed since merge base");
auto mtime = getDirStateMtime();
auto key =
folly::to<std::string>(commitId, ":", mtime.tv_sec, ":", mtime.tv_nsec);
auto commitCopy = folly::to<std::string>(commitId);

std::vector<w_string> lines;
w_string_piece(result.output).split(lines, '\n');
return lines;
return filesChangedSinceMergeBaseWith_
.get(
key,
[this, commit = std::move(commitCopy), requestId](
const std::string&) {
auto result = runMercurial(
{hgExecutablePath(),
"--traceback",
"status",
"-n",
"--rev",
commit,
// The "" argument at the end causes paths to be printed out
// relative to the cwd (set to root path above).
""},
makeHgOptions(requestId),
"query for files changed since merge base");

std::vector<w_string> lines;
w_string_piece(result.output).split(lines, '\n');
return folly::makeFuture(lines);
})
.get()
->value();
}

SCM::StatusResult Mercurial::getFilesChangedBetweenCommits(
Expand Down
2 changes: 2 additions & 0 deletions scm/Mercurial.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Mercurial : public SCM {
private:
std::string dirStatePath_;
mutable LRUCache<std::string, w_string> mergeBases_;
mutable LRUCache<std::string, std::vector<w_string>>
filesChangedSinceMergeBaseWith_;

// Returns options for invoking hg
ChildProcess::Options makeHgOptions(w_string requestId) const;
Expand Down

0 comments on commit 5713a8d

Please sign in to comment.