网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
};
该类包括一个包含消息本身的字符数组。它还可能包括一个Payload(仅用于AppendEntry),以及用于将基本类型消息安全转换为特定类型消息的方法(Maybe方法)和不安全转换(Cast方法)。下面是一个使用MessageHolder的典型例子:
void SomeFunction(TMessageHolder message) {
auto maybeAppendEntries = message.Maybe();
if (maybeAppendEntries) {
auto appendEntries = maybeAppendEntries.Cast();
}
// if we are sure
auto appendEntries = message.Cast();
// usage with overloaded operator->
auto term = appendEntries->Term;
auto nentries = appendEntries->Nentries;
// …
}
在Candidate状态处理程序中有一个真实的例子:
void TRaft::Candidate(TTime now, TMessageHolder message) {
if (auto maybeResponseVote = message.Maybe()) {
OnRequestVote(std::move(maybeResponseVote.Cast()));
} else
if (auto maybeRequestVote = message.Maybe())
{
OnRequestVote(now, std::move(maybeRequestVote.Cast()));
} else
if (auto maybeAppendEntries = message.Maybe())
{
OnAppendEntries(now, std::move(maybeAppendEntries.Cast()));
}
}
这种设计方法提高了Raft实现中消息处理的效率和灵活性。
#### Raft 服务端
让我们讨论一下Raft服务器实现。Raft服务器将为网络交互设置协同程序。首先,我们将查看处理消息读写的协程。本文稍后将讨论用于这些协程的原语,并对网络库进行分析。写协程负责向套接字写入消息,而读协程稍微复杂一些。要读取,它必须首先检索Type和Len变量,然后分配Len字节数组,最后读取消息的其余部分。这种结构促进了Raft服务器内网络通信的高效管理。
template
TValueTask
TMessageWriter::Write(TMessageHolder message) {
co_await TByteWriter(Socket).Write(message.Mes, message->Len);
auto payload = std::move(message.Payload);
for (uint32_t i = 0; i < message.PayloadSize; ++i) {
co_await Write(std::move(payload[i]));
}
co_return;