Ejemplo n.º 1
0
/* This function should be called when the socket is readable.
 * It processes all replies that can be read and executes their callbacks.
 */
void redisAsyncHandleRead(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    // 如果连接已经断开,尝试连接
    if (!(c->flags & REDIS_CONNECTED)) {
        /* Abort connect was not successful. */
        if (__redisAsyncHandleConnect(ac) != REDIS_OK)
            return;
        /* Try again later when the context is still not connected. */
        if (!(c->flags & REDIS_CONNECTED))
            return;
    }

    // 读取数据
    if (redisBufferRead(c) == REDIS_ERR) {
        // 读取错误,断开连接并做一些清理工作
        __redisAsyncDisconnect(ac);
    } else {
        // 读取数据成功,再次注册读事件,
        /* Always re-schedule reads */
        _EL_ADD_READ(ac);

        // 并处理回调函数
        redisProcessCallbacks(ac);
    }
}
Ejemplo n.º 2
0
Archivo: async.c Proyecto: freb/rules
/* This function should be called when the socket is readable.
 * It processes all replies that can be read and executes their callbacks.
 */
void redisAsyncHandleRead(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    if (!(c->flags & REDIS_CONNECTED)) {
        /* Abort connect was not successful. */
        if (__redisAsyncHandleConnect(ac) != REDIS_OK)
            return;
        /* Try again later when the context is still not connected. */
        if (!(c->flags & REDIS_CONNECTED))
            return;
    }

    if (redisBufferRead(c) == REDIS_ERR) {
        __redisAsyncDisconnect(ac);
    } else {
        /* Always re-schedule reads */
#ifdef _WIN32
        // There appears to be a bug in the Linux version of _EL_ADD_READ which will not reschedule
        // the read if already reading. This is a problem if there is a large number of async GET 
        // operations. If the receive buffer is exhausted with the data returned, the read would
        // not be rescheduled, and the async operations would cease. This forces the read to recur.
        _EL_FORCE_ADD_READ(ac);
#else
        _EL_ADD_READ(ac);
#endif
        redisProcessCallbacks(ac);
    }
}
Ejemplo n.º 3
0
/* This function should be called when the socket is readable.
 * It processes all replies that can be read and executes their callbacks.
 */
void redisAsyncHandleRead(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    if (redisBufferRead(c) == REDIS_ERR) {
        __redisAsyncDisconnect(ac);
    } else {
        /* Always re-schedule reads */
        if (ac->ev.addRead) ac->ev.addRead(ac->ev.data);
        redisProcessCallbacks(ac);
    }
}
Ejemplo n.º 4
0
/* This function should be called when the socket is readable.
 * It processes all replies that can be read and executes their callbacks.
 */
void redisAsyncHandleRead(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    if (!(c->flags & REDIS_CONNECTED)) {
        /* Abort connect was not successful. */
        if (__redisAsyncHandleConnect(ac) != REDIS_OK)
            return;
        /* Try again later when the context is still not connected. */
        if (!(c->flags & REDIS_CONNECTED))
            return;
    }

    if (redisBufferRead(c) == REDIS_ERR) {
        __redisAsyncDisconnect(ac);
    } else {
        /* Always re-schedule reads */
        _EL_ADD_READ(ac);
        redisProcessCallbacks(ac);
    }
}
Ejemplo n.º 5
0
 static void test_nonblocking_connection() {
     redisContext *c;
     int wdone = 0;

     test("Calls command callback when command is issued: ");
     c = __connect_nonblock();
     redisSetCommandCallback(c,__test_callback,(void*)1);
     redisCommand(c,"PING");
     test_cond(__test_callback_flags == 1);
     redisFree(c);

     test("Calls disconnect callback on redisDisconnect: ");
     c = __connect_nonblock();
     redisSetDisconnectCallback(c,__test_callback,(void*)2);
     redisDisconnect(c);
     test_cond(__test_callback_flags == 2);
     redisFree(c);

     test("Calls disconnect callback and free callback on redisFree: ");
     c = __connect_nonblock();
     redisSetDisconnectCallback(c,__test_callback,(void*)2);
     redisSetFreeCallback(c,__test_callback,(void*)4);
     redisFree(c);
     test_cond(__test_callback_flags == ((2 << 8) | 4));

     test("redisBufferWrite against empty write buffer: ");
     c = __connect_nonblock();
     test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
     redisFree(c);

     test("redisBufferWrite against not yet connected fd: ");
     c = __connect_nonblock();
     redisCommand(c,"PING");
     test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
               strncmp(c->error,"write:",6) == 0);
     redisFree(c);

     test("redisBufferWrite against closed fd: ");
     c = __connect_nonblock();
     redisCommand(c,"PING");
     redisDisconnect(c);
     test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
               strncmp(c->error,"write:",6) == 0);
     redisFree(c);

     test("Process callbacks in the right sequence: ");
     c = __connect_nonblock();
     redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING");
     redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
     redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING");

     /* Write output buffer */
     wdone = 0;
     while(!wdone) {
         usleep(500);
         redisBufferWrite(c,&wdone);
     }

     /* Read until at least one callback is executed (the 3 replies will
      * arrive in a single packet, causing all callbacks to be executed in
      * a single pass). */
     while(__test_callback_flags == 0) {
         assert(redisBufferRead(c) == REDIS_OK);
         redisProcessCallbacks(c);
     }
     test_cond(__test_callback_flags == 0x010203);
     redisFree(c);

     test("redisDisconnect executes pending callbacks with NULL reply: ");
     c = __connect_nonblock();
     redisSetDisconnectCallback(c,__test_callback,(void*)1);
     redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
     redisDisconnect(c);
     test_cond(__test_callback_flags == 0x0201);
     redisFree(c);
 }