sapling/eden/fs/inodes/ServerState.h
Wez Furlong 28f7b4a0b0 eden: show desktop notification for blob/tree fetch errors
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
2020-02-10 08:28:49 -08:00

173 lines
4.3 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/ThreadLocal.h>
#include <chrono>
#include <memory>
#include "eden/fs/config/CachedParsedFileMonitor.h"
#include "eden/fs/config/ReloadableConfig.h"
#include "eden/fs/telemetry/EdenStats.h"
#ifdef _WIN32
#include "eden/fs/win/utils/Stub.h" // @manual
#endif
#include "eden/fs/fuse/privhelper/UserInfo.h"
#include "eden/fs/model/git/GitIgnoreFileParser.h"
#include "eden/fs/notifications/Notifications.h"
#include "eden/fs/utils/PathFuncs.h"
namespace facebook {
namespace eden {
class Clock;
class EdenConfig;
class FaultInjector;
class PrivHelper;
class ProcessNameCache;
class StructuredLogger;
class TopLevelIgnores;
class UnboundedQueueExecutor;
/**
* ServerState contains state shared across multiple mounts.
*
* This is normally owned by the main EdenServer object. However unit tests
* also create ServerState objects without an EdenServer.
*/
class ServerState {
public:
ServerState(
UserInfo userInfo,
std::shared_ptr<PrivHelper> privHelper,
std::shared_ptr<UnboundedQueueExecutor> threadPool,
std::shared_ptr<Clock> clock,
std::shared_ptr<ProcessNameCache> processNameCache,
std::shared_ptr<StructuredLogger> structuredLogger,
std::shared_ptr<const EdenConfig> edenConfig,
bool enableFaultInjection = false);
~ServerState();
/**
* Set the path to the server's thrift socket.
*
* This is called by EdenServer once it has initialized the thrift server.
*/
void setSocketPath(AbsolutePathPiece path) {
socketPath_ = path.copy();
}
/**
* Get the path to the server's thrift socket.
*
* This is used by the EdenMount to populate the `.eden/socket` special file.
*/
const AbsolutePath& getSocketPath() const {
return socketPath_;
}
/**
* Get the EdenStats object that tracks process-wide (rather than per-mount)
* statistics.
*/
EdenStats& getStats() {
return edenStats_;
}
ReloadableConfig& getReloadableConfig() {
return config_;
}
const ReloadableConfig& getReloadableConfig() const {
return config_;
}
/**
* Get the EdenConfig data.
*
* The config data may be reloaded from disk depending on the value of the
* reload parameter.
*/
std::shared_ptr<const EdenConfig> getEdenConfig(
ConfigReloadBehavior reload = ConfigReloadBehavior::AutoReload) {
return config_.getEdenConfig(reload);
}
/**
* Get the TopLevelIgnores. It is based on the system and user git ignore
* files.
*/
std::unique_ptr<TopLevelIgnores> getTopLevelIgnores();
/**
* Get the UserInfo object describing the user running this edenfs process.
*/
const UserInfo& getUserInfo() const {
return userInfo_;
}
/**
* Get the PrivHelper object used to perform operations that require
* elevated privileges.
*/
PrivHelper* getPrivHelper() {
return privHelper_.get();
}
/**
* Get the thread pool.
*
* Adding new tasks to this thread pool executor will never block.
*/
const std::shared_ptr<UnboundedQueueExecutor>& getThreadPool() const {
return threadPool_;
}
/**
* Get the Clock.
*/
const std::shared_ptr<Clock>& getClock() const {
return clock_;
}
const std::shared_ptr<ProcessNameCache>& getProcessNameCache() const {
return processNameCache_;
}
const std::shared_ptr<StructuredLogger>& getStructuredLogger() const {
return structuredLogger_;
}
FaultInjector& getFaultInjector() {
return *faultInjector_;
}
Notifications* getNotifications() {
return &notifications_;
}
private:
AbsolutePath socketPath_;
UserInfo userInfo_;
EdenStats edenStats_;
std::shared_ptr<PrivHelper> privHelper_;
std::shared_ptr<UnboundedQueueExecutor> threadPool_;
std::shared_ptr<Clock> clock_;
std::shared_ptr<ProcessNameCache> processNameCache_;
std::shared_ptr<StructuredLogger> structuredLogger_;
std::unique_ptr<FaultInjector> const faultInjector_;
ReloadableConfig config_;
folly::Synchronized<CachedParsedFileMonitor<GitIgnoreFileParser>>
userIgnoreFileMonitor_;
folly::Synchronized<CachedParsedFileMonitor<GitIgnoreFileParser>>
systemIgnoreFileMonitor_;
Notifications notifications_;
};
} // namespace eden
} // namespace facebook