2021SC@SDUSC BRPC Code Analysis (14) —— Write data to Server, channel details

2021SC@SDUSC


1. Introduction

        The previous article combined with the echo server side to introduce how the server is created. Next, let's see how to send data after the connection is established.
        This picture was also used in the last article, and the channel in the middle is what we are going to explain today. The transmission of data will be explained in more detail later.
insert image description here
First, what is a channel?
Channel, channel can also be called pipeline. It can read and write at the same time, while the stream can only be read or only written. The channel (Channel) is bidirectional and can be read or written.
Channels can read and write data asynchronously.
Channels can read data from buffers and write data to buffers.
We can see that in the client.cpp below, it is the channel used to realize data interaction. Here, a channel represents a client-to-server communication line.
Since it is communication, there must be a Server server and a Client client. This article will combine the code to take a macro look at what happens when we build a server.  (All the content of this introduction is basically located in server.cpp)
So we do a simple analysis of the channel in this article.

2. Code Analysis

The first is the base class of channel. It can be seen that all channels are based on RpcChannel and Describable of protobuf. There are two functions that need to be implemented. Weight() represents the weight of the current Channel, and CheckHealth() health check. The reason why it becomes a virtual function is because there are many forms of channel, such as SelectiveChannel, PartitionChannel, etc.
insert image description here
Then implement the ChannelOptions class to summarize the options of the channel.
For example, connect_timeout_ms is the connection timeout. Note that this timeout is the connection timeout inside the rpc framework.
timeout_ms controls the timeout of an rpc request.
Notes are very detailed, no longer list them one by one.
insert image description here
The parameters used by default are given in channel.cpp.
insert image description here
Then look at the initialization of the channel. It is also overloaded with multiple versions, all of which are called to InitSingle().
insert image description here
The key content is here. GlobalInitializeOrDie() performs operations such as protocol and load balancing method registration, which only needs to be executed once globally. Then insert this server_addr_and_port into the socketmap and save the corresponding socket_id to _server_id for subsequent use, and the socketmap saves the corresponding relationship between a certain IP+port and socket_id.
insert image description here
Then there is the most important and core CallMethod method. All operations involving pipelines will be completed by calling this function here. Each request will bind a controller, first initialize cntl according to the incoming attributes, etc., then set the protocol and retry mechanism, and the subsequent operations will basically revolve around it.
insert image description here
Then, related assignments are made for the controller of this request, which are mainly divided into two parts. One is that if each timeout parameter is not set, the parameter of _options is used. The connection timeout is more special. As the comment says, since the connection is each RPC calls are often used repeatedly, and it is meaningless to set cntl alone, so use _options directly. The second is the response, packaging function, and calling method related to the actual content of the request.
insert image description here
Next, set the timer and the _deadline_us of the current request completion, timeout and backup_request_ms, etc. need to use the timer. Divided into three cases, one is the case where the backup_request_ms setting is valid, the other is the case where there is no valid backup_request_ms but there is a valid timeout_ms, and the third is the case where there is neither.
In the first case, HandleBackupRequest will be used to set a bthread_timer for backup_request, that is, how long will the backup request be initiated, and timeout_out will be used to form deadline_us. (This Handle and the next Handle both belong to the category of system calls.)
insert image description here
The second type only has timeout, use HandleTimeout as setting bthread_timer and deadline_us, and need to deal with timeout after reaching the point.
insert image description here
When everything is set. You can submit the transfer. The use of cntl->IssueRPC(), this function will be explained in detail when analyzing the controller. The core method is actually to complete the sending of a request by processing various settings.
insert image description here
Finally, implement the two methods of the base class, which is just an ordinary channel class.
Weight will get its value when the controller has lb, otherwise it will be 0. It is the sum of all servers connected to the current Channel.
The CheckHealth() of the common Channel is realized by judging whether the corresponding _lb can be connected to a valid server.
insert image description here

Summarize

The above is all the content introduced today. This article mainly analyzes the source code of the channel in detail based on how to send data, and the subsequent blog will continue to analyze other codes.

Guess you like

Origin blog.csdn.net/m0_46306466/article/details/122179340