LogCabin
|
00001 /* Copyright (c) 2012 Stanford University 00002 * Copyright (c) 2015 Diego Ongaro 00003 * 00004 * Permission to use, copy, modify, and distribute this software for any 00005 * purpose with or without fee is hereby granted, provided that the above 00006 * copyright notice and this permission notice appear in all copies. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 */ 00016 00017 #include <memory> 00018 00019 #include "Client/SessionManager.h" 00020 #include "Core/Config.h" 00021 #include "Core/Mutex.h" 00022 #include "Event/Loop.h" 00023 #include "Event/Signal.h" 00024 #include "Server/ServerStats.h" 00025 00026 #ifndef LOGCABIN_SERVER_GLOBALS_H 00027 #define LOGCABIN_SERVER_GLOBALS_H 00028 00029 namespace LogCabin { 00030 00031 // forward declarations 00032 namespace RPC { 00033 class Server; 00034 } 00035 00036 namespace Server { 00037 00038 // forward declarations 00039 class ClientService; 00040 class ControlService; 00041 class RaftConsensus; 00042 class RaftService; 00043 class StateMachine; 00044 00045 /** 00046 * Holds the LogCabin daemon's top-level objects. 00047 * The purpose of main() is to create and run a Globals object. 00048 * Other classes may refer to this object if they need access to other 00049 * top-level objects. 00050 */ 00051 class Globals { 00052 private: 00053 /** 00054 * Exits from the event loop upon receiving a UNIX signal. 00055 */ 00056 class ExitHandler : public Event::Signal { 00057 public: 00058 ExitHandler(Event::Loop& eventLoop, int signalNumber); 00059 void handleSignalEvent(); 00060 Event::Loop& eventLoop; 00061 }; 00062 00063 /** 00064 * Re-opens the log file upon receiving a UNIX signal. 00065 */ 00066 class LogRotateHandler : public Event::Signal { 00067 public: 00068 LogRotateHandler(Event::Loop& eventLoop, int signalNumber); 00069 void handleSignalEvent(); 00070 Event::Loop& eventLoop; 00071 }; 00072 00073 public: 00074 00075 /// Constructor. 00076 Globals(); 00077 00078 /// Destructor. 00079 ~Globals(); 00080 00081 /** 00082 * Finish initializing this object. 00083 * This should be called after #config has been filled in. 00084 */ 00085 void init(); 00086 00087 /** 00088 * Leave the signals blocked when this object is destroyed. 00089 * This is used in Server/Main.cc for the long-running daemon; it's not 00090 * used in unit tests. 00091 * 00092 * This was added to work around a specific problem: when running the 00093 * servers under valgrind through cluster.py, the servers would receive 00094 * SIGTERM, start to shut down, then the instant the SIGTERM signal was 00095 * unmasked, the server would appear to exit with a 0 status, yet it 00096 * wouldn't finish the shutdown process. I couldn't reproduce this outside 00097 * of cluster.py. As there's no reason to unblock the signals before 00098 * exiting the daemon, this seems like the safer bet for now. 00099 * -Diego 2015-04-29 00100 */ 00101 void leaveSignalsBlocked(); 00102 00103 /** 00104 * Run the event loop until SIGINT, SIGTERM, or someone calls 00105 * Event::Loop::exit(). 00106 */ 00107 void run(); 00108 00109 /** 00110 * Enable asynchronous signal delivery for all signals that this class is 00111 * in charge of. This should be called in a child process after invoking 00112 * fork(), as the StateMachine does. 00113 */ 00114 void unblockAllSignals(); 00115 00116 /** 00117 * Global configuration options. 00118 */ 00119 Core::Config config; 00120 00121 /** 00122 * Statistics and information about the server's current state. Useful for 00123 * diagnostics. 00124 */ 00125 Server::ServerStats serverStats; 00126 00127 /** 00128 * The event loop that runs the RPC system. 00129 */ 00130 Event::Loop eventLoop; 00131 00132 private: 00133 /** 00134 * Block SIGINT, which is handled by sigIntHandler. 00135 * Signals are blocked early on in the startup process so that newly 00136 * spawned threads also have them blocked. 00137 */ 00138 Event::Signal::Blocker sigIntBlocker; 00139 00140 /** 00141 * Block SIGTERM, which is handled by sigTermHandler. 00142 */ 00143 Event::Signal::Blocker sigTermBlocker; 00144 00145 /** 00146 * Block SIGUSR1, which is handled by serverStats. 00147 */ 00148 Event::Signal::Blocker sigUsr1Blocker; 00149 00150 /** 00151 * Block SIGUSR2, which is handled by sigUsr2Handler. 00152 */ 00153 Event::Signal::Blocker sigUsr2Blocker; 00154 00155 /** 00156 * Exits the event loop upon receiving SIGINT (keyboard interrupt). 00157 */ 00158 ExitHandler sigIntHandler; 00159 00160 /** 00161 * Registers sigIntHandler with the event loop. 00162 */ 00163 Event::Signal::Monitor sigIntMonitor; 00164 00165 /** 00166 * Exits the event loop upon receiving SIGTERM (kill). 00167 */ 00168 ExitHandler sigTermHandler; 00169 00170 /** 00171 * Registers sigTermHandler with the event loop. 00172 */ 00173 Event::Signal::Monitor sigTermMonitor; 00174 00175 /** 00176 * Re-opens log files upon receiving SIGUSR2 (user-defined signal). This 00177 * should normally be invoked by tools like logrotate. 00178 */ 00179 LogRotateHandler sigUsr2Handler; 00180 00181 /** 00182 * Registers sigUsr2Handler with the event loop. 00183 */ 00184 Event::Signal::Monitor sigUsr2Monitor; 00185 00186 public: 00187 /** 00188 * A unique ID for the cluster that this server may connect to. This is 00189 * initialized to a value from the config file. If it's not set then, it 00190 * may be set later as a result of learning a UUID from some other server. 00191 */ 00192 Client::SessionManager::ClusterUUID clusterUUID; 00193 00194 /** 00195 * Unique ID for this server. Set from config file. 00196 */ 00197 uint64_t serverId; 00198 00199 /** 00200 * Consensus module. 00201 */ 00202 std::shared_ptr<Server::RaftConsensus> raft; 00203 00204 /** 00205 * State machine used to process client requests. 00206 */ 00207 std::shared_ptr<Server::StateMachine> stateMachine; 00208 00209 private: 00210 00211 /** 00212 * Service used by logcabinctl to query and change a server's internal 00213 * state. 00214 */ 00215 std::shared_ptr<Server::ControlService> controlService; 00216 00217 /** 00218 * Service used to communicate between servers. 00219 */ 00220 std::shared_ptr<Server::RaftService> raftService; 00221 00222 /** 00223 * The application-facing facing RPC service. 00224 */ 00225 std::shared_ptr<Server::ClientService> clientService; 00226 00227 /** 00228 * Listens for inbound RPCs and passes them off to the services. 00229 */ 00230 std::unique_ptr<RPC::Server> rpcServer; 00231 00232 // Globals is non-copyable. 00233 Globals(const Globals&) = delete; 00234 Globals& operator=(const Globals&) = delete; 00235 00236 }; // class Globals 00237 00238 } // namespace LogCabin::Server 00239 } // namespace LogCabin 00240 00241 #endif /* LOGCABIN_SERVER_GLOBALS_H */