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

2022/4/20 2:12:29

本文主要是介绍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; }     未完待续

这篇关于redis源码阅读3----客户端连接过程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程