2021SC@SDUSC

回到CallMethod函数。

接下来将设置各种成员,如超时时间,response等,因为demo中场景没有设置loadbalancer,所以是SingleServer

通过_serialize_request,这里会把request序列化到controller的request_buf,原因是为了重试,一个RPC过程中只会调用一次。然后启动定时任务处理超时。

接下来就是真正的连接和发送了

然后看下controller的IssueRPC。

首先通过current_id()得到该次请求的CallId,如上所述,第一次请求版本号为1 + 0 + 1 = 2

然后通过server_id获取到Socket保存在tmp_sock中、

因为当前使用的是单连接,所以直接将sending_sock指向tmp_sock,然后调用协议的pack_request,本例中协议为baidu_std,将_request_buf,correlation_id等打包到packet中,每次请求前都会调用,包括重试,其中attachment不会经过序列化,而是直接原始的二进制数据。

然后调用Write方法将数据写入Socket。

brpc在多线程向fd写数据时实现了wait-free,这部分逻辑已经抽出单独的ExecutionQueue,之前的文章已经分析过,这里再简单看下。

先新建一个WriteRequest,WriteRequest就是ExecutionQueue中的节点结构,req中的data设置为本次请求要发送的数据data,然后指向UNCONNECTED,然后执行StartWrite

首先通过exchange原子修改当前队列头节点_write_head为新建的req,并返回旧的头节点prev_head,如果prev_head不为null,那么说明当前有bthread在向fd中写数据,因为这个bthread写完队列中所有的WriteRequest,因此直接将req链入队列即可。如果prev_head是null,那么当前线程/bthread就会去写数据。

然后开始调用ConnectIfNot

到现在为止,client端其实还没有向server端发起连接,因此fd为-1,于是调用Connect建立连接。

为了性能的考虑,brpc使用的是异步连接,然后复用EventDispatcher的逻辑来epoll通知连接事件的完成。具体的,首先新建一个socket,然后设置为non_blocking,然后调用connect连接server。

新建一个EpollOutRequest req,设置req的fd和data,然后新建一个Socket connect_id,新建这个Socket的目的就是上文提到的复用EventDispatcher逻辑(这两个Socket的"回调函数"不一样)。新建的Socket的user为这个req。

然后向EventDispatcher中注册epoll out事件。

回到StartWrite的1529行,此时返回的是1,表示正在连接,因此直接返回到IssueRPC执行bthread_id_unlock。

该函数是对ID对象的释放,首先获取到ID对象,此时ID的butex要么是locked,要么是contended,首先要将butex置为first_ver,如果当前状态为contended,那么说明有其他线程/bthread被butex_wait挂起在该butex上,因此使用butex_wake唤醒他,继续竞争ID对象。

此时IssueRPC执行结束了,假设此时完成了对server端的连接,那么将会产生epollout事件,如下:

直接调用HandleEpollOut,data.u64在上文的Connect中被设置为了新建的Socket connect_id。

Brpc代码分析-Server端(九)相关推荐

  1. Hadoop基于Protocol Buffer的RPC实现代码分析-Server端--转载

    原文地址:http://yanbohappy.sinaapp.com/?p=110 最新版本的Hadoop代码中已经默认了Protocol buffer(以下简称PB,http://code.goog ...

  2. 2021SC@SDUSC BRPC代码分析(七) —— bthread综述、Butex及mutex详解

    2021SC@SDUSC 文章目录 一.bthread的背景知识学习 二.代码分析 总结 一.bthread的背景知识学习 经过前面6篇代码分析,我将BRPC一个极其实用的工具--bvar做了全面系统 ...

  3. elasticsearch源码分析之search模块(server端)

    elasticsearch源码分析之search模块(server端) 继续接着上一篇的来说啊,当client端将search的请求发送到某一个node之后,剩下的事情就是server端来处理了,具体 ...

  4. brpc源码学习(六)- brpc server 端整体流程

    brpc的使用比较容易上手,以官方demo为例,因为brpc的数据序列化依赖protobuf,所以首先需要定义个proto 然后继承EchoService并实现Echo方法 然后是整体流程 启动还是比 ...

  5. WFD连接过程代码分析(Sink端)

    WFD连接过程代码分析(Sink端) WFD建立连接首先必需建立P2P连接,随后WFD使用P2P连接的IP和端口号建立RTSP连接.本文着重分析P2P连接建立后的RTSP连接建立过程,且为一个Sour ...

  6. 完整mes代码(含客户端和server端_Ice简介+Qt代码示例

    一.ICE是什么? ICE是ZEROC的开源通讯协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通讯引擎,是一个面向对象的中间件,它封装并 ...

  7. 完整mes代码(含客户端和server端_200行代码实现基于paxos的kv存储

    本文链接: https://blog.openacid.com/algo/paxoskv/ 前言 写完 paxos的直观解释 之后, 网友都说疗效甚好, 但是也会对这篇教程中一些环节提出疑问(有疑问说 ...

  8. 团队项目开发“编码规范”之九:代码分析

    团队项目开发"编码规范"之九: 代码分析 发布日期:2011年3月17日星期三作者:EricHu                                           ...

  9. 代码分析-DataGrid实现自增列、单选、多选

    上一次,我们为这个DataGrid实现了添加.删除.修改.分页.动态修改内容等功能,今天再来分析一下如何为之添加自增列.单选.多选的功能. 首先看一下需要在上次的基础上增加的代码: (1)实现自增列 ...

最新文章

  1. mongodb性能分析方法:explain()
  2. Android本地存储键值对,flutter本地存储键值对简单数据(相当于web的localstorage) 代码实现...
  3. Leetcode 930:和相同的二元子数组
  4. Java 算法 吉老师的回归
  5. Python webdriver 读取本地csv文件中数据 提示:IOError: [Errno 2] No such file or directory
  6. 软件生命周期是指什么?
  7. mod mpm event php7.1,CentOS 7 安裝 PHP-FPM 及使用 mod_mpm_event
  8. 母婴广告投放在哪里合适?如何在抖音投放广告抢占市场?
  9. VS2005宏无法运行的问题(打了补丁MS14-009之后)
  10. 面试大全 | C语言高级部分总结
  11. c语言凑数的不同种方法,凑数强化版【庆贺2021年5月9日母亲节】
  12. 原 python实现水仙花数_Python实现水仙花数
  13. Bugku 杂项 中国菜刀
  14. SATA硬盘和IDE硬盘的区别
  15. web应用防火墙是什么?有哪些作用?
  16. 面试的时候被问如何看待加班,该怎么回答?
  17. A Tour of C++
  18. HBuilderX下载安装以及打包uniapp项目
  19. DSR (串口通信中的术语)
  20. 在线扫描PDF JPG 图片上面文字

热门文章

  1. css语法,常用css语法,内部样式表,外部样式表,内联样式表, 样式优先级问题
  2. 「CSS」文本编排相关的CSS属性设置
  3. vue3本地图片加载不出来,解决方法
  4. MT9V034摄像头学习笔记(二)
  5. 使用golang发送电子邮件
  6. VC的监视窗口等调试窗口的使用
  7. 课程设计:通讯录系统(数据库)
  8. 论文阅读 || 目标检测系列 —— RCNN详解
  9. GitHub搭建的个人博客发表文章
  10. 手把手教你从零写一个日志框架