LogCabin
Server/RaftService.cc
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines