mongodb 异步查询(续)

本文介绍了一个使用C语言和LUA结合开源mongodb c driver实现的异步查询接口。通过拆分同步查询为三个步骤:创建并发送请求、接收并处理响应。文章详细阐述了请求发送过程,包括生成query id、填充请求内容和保存数据库操作对象,并展示了C接口和LUA接口的实现。同时,解释了接收并处理响应时解析消息头和处理数据的逻辑,以及如何将结果封装到LUA逻辑层。最后,对整个异步查询流程进行了总结。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  承接前一篇, 服务器采用C编写, 逻辑层使用LUA, 搭配开源mongodb c driver开发异步查询接口.


  有了上一次的改造, 这次来说说是如何使用改造后的接口实现异步查询.


  首先, 再来理清一下思路, 现在的一次完整同步查询被拆分成3个步骤:

  1.创建并发送请求

 

  2.接受返回结果消息头

  3.接受返回结果数据并做相应的回调处理

 

   为此我们需要2个结构来处理这个过程:

    

 

   上图的第一个结构为网络连接内部参数, 用于每次回调处理recv的时候取数据.

   第二个结构为hash表中的数据, 用每次异步请求ID作为KEY.

 

   下面会分别对这三个阶段进行讲解:

请求发送:

   ok, 请求发送时, 首先我们需要为该次异步请求生成一个query id, 该id可以采用例如UUID类的方法生成, 也可以简单的使用自增ID.

   其次, 填充本次请求内容, 并将数据库操作对象保存至hashtbl(query id作key), 将请求发送给DB.

   最后, 将query id返回给LUA逻辑层, 挂起当前coroutine.

 

   C 接口如下:

    

 

   LUA 层接口:

       

 

接收并处理响应:

   这里面共包含2个部分, 处理消息头和处理消息数据并打包至逻辑层.

   为什么这里面要把解析头部和处理数据部分分开, 是因为头部长度固定, 我们可以一次读取完成, 但是后续的数据长度是从头部信息中获取

得到的, 我们没办法在一开始就确定一共要读多长的数据, 故要分开处理.

 

   解析头部: 

      固定读取定长消息头, 得到后续数据长度和query id 并得到mongo_reply, 我们需要保存该mongo_reply以便后续处理.

      这里面我们再次用到了query id, 用其将mongo_reply保存至请求时的hash结构指定KEY中.

 

   处理数据:

      此时由于本次接受到的数据并非一定满足后续数据长度, 故有可能中断, 但是好在该次响应在网络层面上数据是连贯的, 所以我们在读取

完整响应期间, 可以利用网络框架帮助我们保存一些临时参数, 比如保存query id, 这样即使在非连贯的读取一次响应数据时也不会因为

获取query id而产生不必要的麻烦.

      这样当我们读取完整数据后, 就可以封装结果至逻辑层使用了 :)

 

   接受逻辑:

    

 

   在处理数据时, 再次从hashtbl中获取了"ns", 写到这里, 大家应该明白了为什么使用一个hashtbl来保存这个ns, 而不是直接放在网络框架中

做临时参数处理, 因为每次异步请求都会得到ns, 但我们又不能保证每次都是一样, 请求和响应并非连贯导致了临时保存的结果可能是错误的也

可能是刚刚被置空了... 

 

   封装结果至LUA逻辑层, 这里就不列举代码了, 简单说下, 就是将结果保存为一维线性, 二维hash的lua table中.

   然后调用逻辑层唤醒指定query id的coroutine继续执行.

 

    

 

 

总结:

   至此, 一个完整的异步查询请求就编写完成, 由于时间关系, 代码层面上还有很多可以精简优化的余地,  我在此仅仅作为提供思路, 欢迎一同探讨 :)

email : hyzwowtools@163.com

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值