Redis Clusterの実装-初期化(2)



2)リスニングキットインタフェースでaeCreateFileEvent()を呼び出してイベントプロセッサを設定し、署名された呼び出しから設定されたACCEPTイベントプロセッサがclusterAcceptHandler()であることがわかる.
aeCreateFileEvent(server.el, server.cfd[j], AE_READABLE, clusterAcceptHandler, NULL);

 
//            
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
      aeFileProc *proc, void *clientData)
{
    if (fd >= eventLoop->setsize) {
        errno = ERANGE;
        return AE_ERR;
    }
    aeFileEvent *fe = &eventLoop->events[fd];
    
    //        fd        
    //                I/O   
    //  : Linux    epoll
    if (aeApiAddEvent(eventLoop, fd, mask) == -1)
        return AE_ERR;
        
    fe->mask |= mask;
    
    //      read/write           
    //        READ        clusterAcceptHandler()
    if (mask & AE_READABLE) fe->rfileProc = proc;
    if (mask & AE_WRITABLE) fe->wfileProc = proc;
    fe->clientData = clientData;
    if (fd > eventLoop->maxfd)
        eventLoop->maxfd = fd;
    return AE_OK;
}

以上のようにACCEPTイベントプロセッサを追加すると、新しい接続がある場合、clusterAcceptHandler()がコールバックされ、新しい接続が処理されます.    
//             1000    
#define MAX_CLUSTER_ACCEPTS_PER_CALL 1000
// fd        
// privdata      aeCreateFileEvent()      clientdata   ,    NULL
void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
    int cport, cfd;
    int max = MAX_CLUSTER_ACCEPTS_PER_CALL;
    char cip[REDIS_IP_STR_LEN];
    clusterLink *link;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);
    REDIS_NOTUSED(privdata);
    /* If the server is starting up, don't accept cluster connections:
     * UPDATE messages may interact with the database content. */
    if (server.masterhost == NULL && server.loading) return;
    
    //    MAX_CLUSTER_ACCEPTS_PER_CALL         
    while(max--) {
        
        //            cfg
        // cip       
        // cport      socket      
        cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
        if (cfd == ANET_ERR) {
            if (errno != EWOULDBLOCK)
                redisLog(REDIS_VERBOSE,
                    "Accepting cluster node: %s", server.neterr);
            return;
        }
        
        //           socket      
        anetNonBlock(NULL,cfd);
        
        //      socket    TCP_NODELAY(   TCP   Nagle   )
        anetEnableTcpNoDelay(NULL,cfd);
        /* Use non-blocking I/O for cluster messages. */
        redisLog(REDIS_VERBOSE,"Accepted cluster node %s:%d", cip, cport);
        
        /* Create a link object we use to handle the connection.
         * It gets passed to the readable handler when data is available.
         * Initiallly the link->node pointer is set to NULL as we don't know
         * which node is, but the right node is references once we know the
         * node identity. */
        link = createClusterLink(NULL);
        link->fd = cfd;
        aeCreateFileEvent(server.el,cfd,AE_READABLE,clusterReadHandler,link);
    }
}

 
クライアント接続(ここでは他のノードの接続を表す)を正常に受信した後、clusterリンクを作成し、readイベントプロセッサclusterReadHandlerを初期化します.redis clusterに関する各ノードの初期化部分はほぼ終了し,以下では接続を受信し,受信したデータ,コンポーネントclusterを処理するのを待つ.[次編ではclusterReadHandlerの実装を分析する予定です.]