redis源码分析(4)——发送响应内容

前一篇介绍了redis处理请求的过程,接下来是如何发送响应内容。
  在请求处理完之后,进行响应时,需要调用addReplyXXX族函数,具体包括:
           void addReply(redisClient *c, robj *obj)
           void addReplySds(redisClient *c, sds s)
           void addReplyString(redisClient *c, char *s, size_t len)
      这几个函数又会被封装成addReplyBulk等函数。这里以addReply为例进行分析。
首先,先介绍一下北京知识。redis将响应内容组织成两部分,一个固定大小的buffer(16KB),一个响应内容对象的链表。在链表为空并且buffer有足够空间时,则将响应添加到buffer中,否则创建一个节点追加到链表上。固定buffer和响应链表,整体上构成了一个队列。这么组织的好处是,既可以节省内存(不需一开始预先分配大块内存,动态内存的由链表cover),并且可以避免频繁分配、回收内存(在响应内容小于buffer大小时)。
在addReply函数中,首先会调用prepareClientToWrite,在响应前进行初始化工作。
 if (prepareClientToWrite(c) != REDIS_OK) return;
prepareClientToWrite函数在每次发送响应时调用,并且要在向响应buffer添加数据之前。只有在返回REDIS_OK时,才能向响应buffer输出内容。在响应buffer为空时(固定buffer以及链表均为空)时,向事件循环注册写事件,回调函数是sendReplyToClient。
/* This function is called every time we are going to transmit new data
 * to the client. The behavior is the following:
 *
 * If the client should receive new data (normal clients will) the function
 * returns REDIS_OK, and make sure to install the write handler in our event
 * loop so that when the socket is writable new data gets written.
 *
 * If the client should not receive new data, because it is a fake client,
 * a master, a slave not yet online, or because the setup of the write handler
 * failed, the function returns REDIS_ERR.
 *
 * Typically gets called every time a reply is built, before adding more
 * data to the clients output buffers. If the function returns REDIS_ERR no
 * data should be appended to the output buffers. */
int prepareClientToWrite(redisClient *c) {
    if (c->flags & REDIS_LUA_CLIENT) return REDIS_OK;
    if ((c->flags & REDIS_MASTER) &&
        !(c->flags & REDIS_MASTER_FORCE_REPLY)) return REDIS_ERR;
    if (c->fd <= 0) return REDIS_ERR; /* Fake client */
    // <MM>
    // 在没有向output buf输出之前,才可以注册write event hand
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值