in watchman/root/watchlist.cpp [140:275]
json_ref Root::getStatus() const {
auto obj = json_object();
auto now = std::chrono::steady_clock::now();
auto cookie_array = json_array();
for (auto& name : cookies.getOutstandingCookieFileList()) {
cookie_array.array().push_back(w_string_to_json(name));
}
std::string crawl_status;
auto recrawl_info = json_object();
{
auto info = recrawlInfo.rlock();
recrawl_info.set({
{"count", json_integer(info->recrawlCount)},
{"should-recrawl", json_boolean(info->shouldRecrawl)},
{"warning", w_string_to_json(info->warning)},
});
if (!inner.done_initial) {
crawl_status = folly::to<std::string>(
info->recrawlCount ? "re-" : "",
"crawling for ",
std::chrono::duration_cast<std::chrono::milliseconds>(
now - info->crawlStart)
.count(),
"ms");
} else if (info->shouldRecrawl) {
crawl_status = folly::to<std::string>(
"needs recrawl: ",
info->warning.view(),
". Last crawl was ",
std::chrono::duration_cast<std::chrono::milliseconds>(
now - info->crawlFinish)
.count(),
"ms ago");
} else {
crawl_status = folly::to<std::string>(
"crawl completed ",
std::chrono::duration_cast<std::chrono::milliseconds>(
now - info->crawlFinish)
.count(),
"ms ago, and took ",
std::chrono::duration_cast<std::chrono::milliseconds>(
info->crawlFinish - info->crawlStart)
.count(),
"ms");
}
}
auto query_info = json_array();
{
auto locked = queries.rlock();
for (auto& ctx : *locked) {
auto info = json_object();
auto elapsed = now - ctx->created;
const char* queryState = "?";
switch (ctx->state.load()) {
case QueryContextState::NotStarted:
queryState = "NotStarted";
break;
case QueryContextState::WaitingForCookieSync:
queryState = "WaitingForCookieSync";
break;
case QueryContextState::WaitingForViewLock:
queryState = "WaitingForViewLock";
break;
case QueryContextState::Generating:
queryState = "Generating";
break;
case QueryContextState::Rendering:
queryState = "Rendering";
break;
case QueryContextState::Completed:
queryState = "Completed";
break;
}
info.set({
{"elapsed-milliseconds",
json_integer(
std::chrono::duration_cast<std::chrono::milliseconds>(elapsed)
.count())},
{"cookie-sync-duration-milliseconds",
json_integer(ctx->cookieSyncDuration.load().count())},
{"generation-duration-milliseconds",
json_integer(ctx->generationDuration.load().count())},
{"render-duration-milliseconds",
json_integer(ctx->renderDuration.load().count())},
{"view-lock-wait-duration-milliseconds",
json_integer(ctx->viewLockWaitDuration.load().count())},
{"state", typed_string_to_json(queryState)},
{"client-pid", json_integer(ctx->query->clientPid)},
{"request-id", w_string_to_json(ctx->query->request_id)},
{"query", json_ref(ctx->query->query_spec)},
});
if (ctx->query->subscriptionName) {
info.set(
"subscription-name",
w_string_to_json(ctx->query->subscriptionName));
}
query_info.array().push_back(info);
}
}
auto cookiePrefix = cookies.cookiePrefix();
auto jsonCookiePrefix = json_array();
for (const auto& name : cookiePrefix) {
jsonCookiePrefix.array().push_back(w_string_to_json(name));
}
auto cookieDirs = cookies.cookieDirs();
auto jsonCookieDirs = json_array();
for (const auto& dir : cookieDirs) {
jsonCookieDirs.array().push_back(w_string_to_json(dir));
}
obj.set({
{"path", w_string_to_json(root_path)},
{"fstype", w_string_to_json(fs_type)},
{"case_sensitive",
json_boolean(case_sensitive == CaseSensitivity::CaseSensitive)},
{"cookie_prefix", std::move(jsonCookiePrefix)},
{"cookie_dir", std::move(jsonCookieDirs)},
{"cookie_list", std::move(cookie_array)},
{"recrawl_info", std::move(recrawl_info)},
{"queries", std::move(query_info)},
{"done_initial", json_boolean(inner.done_initial)},
{"cancelled", json_boolean(inner.cancelled)},
{"crawl-status",
w_string_to_json(w_string(crawl_status.data(), crawl_status.size()))},
});
return obj;
}