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; } 未完待续
标签:write,ln,clients,redis,client,----,源码,server,客户端 来源: https://www.cnblogs.com/white-zhan/p/16168077.html