微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

redis源码阅读3----客户端连接过程

本章主要讨论在client连接到server时。server在ae过程中是如何处理的。

主要讨论的是接口函数

 

由于是初次debug。为了保险起见我还是把断点打在了aemain上。

然后在客户端执行redis-cli -p 7000

后执行

if (eventLoop->beforesleep != NULL && flags & AE_CALL_BEFORE_SLEEP)             eventLoop->beforesleep(eventLoop);  

时,连接redis server成功。也就是说,客户端连接部分的代码全在beforesleep(eventLoop);里。

 

我们接着往下看。

进入函数,进一步分析得到,处理链接在这一步进行:networking.c下

handleClientsWithPendingWritesUsingThreads();   首先判断这个队列下有没有元素,如果没有的话,这个函数就直接return了,上一章也分析过。 int processed = listLength(server.clients_pending_write);   此段注释:如果I/O线程被禁用,或者我们需要服务的客户机很少,就不要使用I/O线程,而是使用同步代码(synchronous code)。 这里的I/O线程被禁用不能理解,然后的话,这里客户机很少,从代码中不难看出,很少就是1个线程。 if (server.io_threads_num == 1 || stopThreadedioIfNeeded()) {         return handleClientsWithPendingWrites();     }   然后我们看一下handleClientsWithPendingWrites()函数: 这个函数在进入事件循环前调用,可以直接将replies写入client output buffer,而不用进行syscall去安装writable event handler。 int handleClientsWithPendingWrites(void) {     listIter li;     listNode *ln;     int processed = listLength(server.clients_pending_write);
    listRewind(server.clients_pending_write,&li);     while((ln = listNext(&li))) {         client *c = listNodeValue(ln);         c->flags &= ~CLIENT_PENDING_WRITE;         listDelNode(server.clients_pending_write,ln);
        /* If a client is protected, don't do anything,          * that may trigger write error or recreate handler. */ 客户端受保护是什么状态。先留下疑问。         if (c->flags & CLIENT_PROTECTED) continue;
        /* Don't write to clients that are going to be closed anyway. */这个很正常。对要关闭的client就不写入了         if (c->flags & CLIENT_CLOSE_ASAP) continue;
        /* Try to write buffers to the client socket. */对客户端写入。这也是客户端连接的主要函数。writetoClient(c,0)         if (writetoClient(c,0) == C_ERR) continue;
        /* If after the synchronous writes above we still have data to          * output to the client, we need to install the writable handler. */         if (clientHasPendingReplies(c)) {             int ae_barrier = 0;             /* For the fsync=always policy, we want that a given FD is never              * served for reading and writing in the same event loop iteration,              * so that in the middle of receiving the query, and serving it              * to the client, we'll call beforeSleep() that will do the              * actual fsync of AOF to disk. the write barrier ensures that. */             if (server.aof_state == AOF_ON &&                 server.aof_fsync == AOF_FSYNC_ALWAYS)             {                 ae_barrier = 1;             }             if (connSetWriteHandlerWithBarrier(c->conn, sendReplyToClient, ae_barrier) == C_ERR) {                 freeClientAsync(c);             }         }     }     return processed; }     未完待续

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐