mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
28f7b4a0b0
Summary: This commit causes a desktop notification to be shown if we generate EIO or ETIMEDOUT responses via fuse; the prompt is intended to make it obvious to the user that they need to connect to the VPN. The commit by itself doesn't show a notification, it allows configuring a command that can be run to do something to show a notification. The test plan includes one such configuration for our corp environment. * It doesn't trigger for thrift-originated downloads (eg: prefetch), only for VFS operations through FUSE. * Ideally we'd know exactly when we have a network related error in the store code and use that to trigger the notification. However, we have a rather convoluted set of importers and fallbacks today, one of which is interpreting a generic response returned from a pipe, so it is not especially clear exactly where we should locate the logic Reviewed By: chadaustin Differential Revision: D17513364 fbshipit-source-id: 45134f3672679cb5580cb0c1bc12a0d6e38525ca
64 lines
1.6 KiB
C++
64 lines
1.6 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.
|
|
*/
|
|
|
|
#include "eden/fs/notifications/Notifications.h"
|
|
|
|
#include <folly/Subprocess.h>
|
|
#include <folly/futures/Future.h>
|
|
#include "eden/fs/config/EdenConfig.h"
|
|
#include "eden/fs/config/ReloadableConfig.h"
|
|
#include "eden/fs/utils/SystemError.h"
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
bool Notifications::canShowNotification() {
|
|
auto now = std::chrono::steady_clock::now();
|
|
auto last = lastShown_.wlock();
|
|
if (*last) {
|
|
auto expiry = last->value() +
|
|
config_.getEdenConfig()->notificationInterval.getValue();
|
|
if (now < expiry) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
namespace {
|
|
bool isGenericConnectivityError(const std::exception& err) {
|
|
int errnum = EIO;
|
|
if (auto* sys = dynamic_cast<const std::system_error*>(&err)) {
|
|
if (isErrnoError(*sys)) {
|
|
errnum = sys->code().value();
|
|
}
|
|
} else if (auto* timeout = dynamic_cast<const folly::FutureTimeout*>(&err)) {
|
|
errnum = ETIMEDOUT;
|
|
}
|
|
return errnum == EIO || errnum == ETIMEDOUT;
|
|
}
|
|
} // namespace
|
|
|
|
void Notifications::showGenericErrorNotification(const std::exception& err) {
|
|
if (!isGenericConnectivityError(err)) {
|
|
return;
|
|
}
|
|
|
|
if (!canShowNotification()) {
|
|
return;
|
|
}
|
|
*lastShown_.wlock() = std::chrono::steady_clock::now();
|
|
|
|
folly::Subprocess proc(
|
|
{"/bin/sh",
|
|
"-c",
|
|
config_.getEdenConfig()->genericErrorNotificationCommand.getValue()},
|
|
folly::Subprocess::Options().detach());
|
|
}
|
|
} // namespace eden
|
|
} // namespace facebook
|