LogCabin
|
00001 /* Copyright (c) 2012 Stanford University 00002 * 00003 * Permission to use, copy, modify, and distribute this software for any 00004 * purpose with or without fee is hereby granted, provided that the above 00005 * copyright notice and this permission notice appear in all copies. 00006 * 00007 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00008 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00009 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00010 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00011 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00012 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00013 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00014 */ 00015 00016 #include "build/Protocol/Raft.pb.h" 00017 #include "Core/Debug.h" 00018 #include "Core/ProtoBuf.h" 00019 #include "RPC/ServerRPC.h" 00020 #include "Server/RaftConsensus.h" 00021 #include "Server/RaftService.h" 00022 #include "Server/Globals.h" 00023 00024 namespace LogCabin { 00025 namespace Server { 00026 00027 RaftService::RaftService(Globals& globals) 00028 : globals(globals) 00029 { 00030 } 00031 00032 RaftService::~RaftService() 00033 { 00034 } 00035 00036 void 00037 RaftService::handleRPC(RPC::ServerRPC rpc) 00038 { 00039 using Protocol::Raft::OpCode; 00040 00041 // Call the appropriate RPC handler based on the request's opCode. 00042 switch (rpc.getOpCode()) { 00043 case OpCode::APPEND_ENTRIES: 00044 appendEntries(std::move(rpc)); 00045 break; 00046 case OpCode::INSTALL_SNAPSHOT: 00047 installSnapshot(std::move(rpc)); 00048 break; 00049 case OpCode::REQUEST_VOTE: 00050 requestVote(std::move(rpc)); 00051 break; 00052 default: 00053 WARNING("Client sent request with bad op code (%u) to RaftService", 00054 rpc.getOpCode()); 00055 rpc.rejectInvalidRequest(); 00056 } 00057 } 00058 00059 std::string 00060 RaftService::getName() const 00061 { 00062 return "RaftService"; 00063 } 00064 00065 /** 00066 * Place this at the top of each RPC handler. Afterwards, 'request' will refer 00067 * to the protocol buffer for the request with all required fields set. 00068 * 'response' will be an empty protocol buffer for you to fill in the response. 00069 */ 00070 #define PRELUDE(rpcClass) \ 00071 Protocol::Raft::rpcClass::Request request; \ 00072 Protocol::Raft::rpcClass::Response response; \ 00073 if (!rpc.getRequest(request)) \ 00074 return; 00075 00076 ////////// RPC handlers ////////// 00077 00078 void 00079 RaftService::appendEntries(RPC::ServerRPC rpc) 00080 { 00081 PRELUDE(AppendEntries); 00082 //VERBOSE("AppendEntries:\n%s", 00083 // Core::ProtoBuf::dumpString(request).c_str()); 00084 globals.raft->handleAppendEntries(request, response); 00085 rpc.reply(response); 00086 } 00087 00088 void 00089 RaftService::installSnapshot(RPC::ServerRPC rpc) 00090 { 00091 PRELUDE(InstallSnapshot); 00092 //VERBOSE("InstallSnapshot:\n%s", 00093 // Core::ProtoBuf::dumpString(request).c_str()); 00094 globals.raft->handleInstallSnapshot(request, response); 00095 rpc.reply(response); 00096 } 00097 00098 void 00099 RaftService::requestVote(RPC::ServerRPC rpc) 00100 { 00101 PRELUDE(RequestVote); 00102 //VERBOSE("RequestVote:\n%s", 00103 // Core::ProtoBuf::dumpString(request).c_str()); 00104 globals.raft->handleRequestVote(request, response); 00105 rpc.reply(response); 00106 } 00107 00108 00109 } // namespace LogCabin::Server 00110 } // namespace LogCabin