为了能够单步调试,需要修改tools目录下的create_makefile.py文件
修改添加 -g
makefile.write(“CPPFLAGS+=$(%s) -g\n\n” % extra_cpp_flag_name)
然后
build.sh
make clean
make
make install
// 还需要重新编译plugin
然后编译运行sample,就可以使用调试程序调试了
class PNode : public Node
{
public:
... ...
private:
// 多个Group的列表
std::vector<Group *> m_vecGroupList;
// 每一个Group对应的Master
std::vector<MasterMgr *> m_vecMasterList;
//
std::vector<ProposeBatch *> m_vecProposeBatch;
private:
MultiDatabase m_oDefaultLogStorage;
DFNetWork m_oDefaultNetWork;
NotifierPool m_oNotifierPool;
nodeid_t m_iMyNodeID;
};
每一个PNode都包含多个Group,每一个Group都有一个对应的Master和ProposeBatch。
DFNetWork表示默认网络,也就是NetWork类,实现了基于事件的异步回调机制。
class Group
{
public:
......
private:
Communicate m_oCommunicate;
Config m_oConfig;
// 然后每一个group都有自己的instance
Instance m_oInstance;
int m_iInitRet;
std::thread * m_poThread;
};
关键点时每一个group都包含一个Instance。
class Instance
{
public:
......
private:
Config * m_poConfig;
MsgTransport * m_poMsgTransport;
SMFac m_oSMFac;
IOLoop m_oIOLoop;
// 每一个Instance都同时是Acceptor, Learner, Proposer
Acceptor m_oAcceptor;
Learner m_oLearner;
Proposer m_oProposer;
PaxosLog m_oPaxosLog;
uint32_t m_iLastChecksum;
......
};
Instance表示一个Paxos实例,同时包含了Acceptor,Leaner, Proposer。
class NetWork
{
public:
NetWork();
virtual ~NetWork() {}
//Network must not send/recieve any message before paxoslib called this funtion.
virtual void RunNetWork() = 0;
//If paxoslib call this function, network need to stop receive any message.
virtual void StopNetWork() = 0;
virtual int SendMessageTCP(const int iGroupIdx, const std::string & sIp, const int iPort, const std::string & sMessage) = 0;
virtual int SendMessageUDP(const int iGroupIdx, const std::string & sIp, const int iPort, const std::string & sMessage) = 0;
//When receive a message, call this funtion.
//This funtion is async, just enqueue an return.
int OnReceiveMessage(const char * pcMessage, const int iMessageLen);
private:
friend class Node;
Node * m_poNode;
};
NetWork类是phxpaxos进行通信的基石。
支持tcp和udp两种通信方式,实现了基于事件的异步回调机制。
Group之中会初始化自己的Network,并且为他们设置回调函数,那么之后要发送消息只需要将消息放到message队列中即可。
创建两个变量oMyNode, vecNodeInfoList分别表示一个Group之中当前节点的ip地址等信息和其他节点的信息。
创建EchoServer(oMyNode, vecNodeInfoList){
调用EchoServer.RunPaxos(){
初始化日志信息和Option结构体
调用Node::RunNode(Option, Node*){
创建RealNode,PNode类型结构体
初始化RealNode,PNode::Init{
初始化日志
初始化网络
初始化MasterList,GroupList,ProposeBatch
初始化状态机InitStatMachine()
多线程,异步方式初始化Group,Group::StartInit(){
Group::Init(){
Instance::Init(){
Acceptor::Init()
...
}
}
启动Group, Group::Start(){
m_oInstance::Start(){
m_oLearner.StartLearnerSender();
m_oIOLoop.start();
m_oCheckpointMgr.Start();
}
}
启动Master, RunMaster()
启动proposeBatch,RunProposeBatch();
启动网络RealNode->RunNetWork(){
UDPSend.start()
UDPRecv.start()
TcpIOThread.start()
}
}
到这里,整个PNode就完全启动起来了。
}
代码中的Master指的是真正的Master还是Leader
BreakPoint的功能是什么。
StatMachine实现了怎样的一个状态机。
IOloop类的功能是什么