| 495 | } |
| 496 | |
| 497 | static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { |
| 498 | client c = privdata; |
| 499 | void *reply = NULL; |
| 500 | UNUSED(el); |
| 501 | UNUSED(fd); |
| 502 | UNUSED(mask); |
| 503 | |
| 504 | /* Calculate latency only for the first read event. This means that the |
| 505 | * server already sent the reply and we need to parse it. Parsing overhead |
| 506 | * is not part of the latency, so calculate it only once, here. */ |
| 507 | if (c->latency < 0) c->latency = ustime()-(c->start); |
| 508 | |
| 509 | if (redisBufferRead(c->context) != REDIS_OK) { |
| 510 | fprintf(stderr,"Error: %s\n",c->context->errstr); |
| 511 | exit(1); |
| 512 | } else { |
| 513 | while(c->pending) { |
| 514 | if (redisGetReply(c->context,&reply) != REDIS_OK) { |
| 515 | fprintf(stderr,"Error: %s\n",c->context->errstr); |
| 516 | exit(1); |
| 517 | } |
| 518 | if (reply != NULL) { |
| 519 | if (reply == (void*)REDIS_REPLY_ERROR) { |
| 520 | fprintf(stderr,"Unexpected error reply, exiting...\n"); |
| 521 | exit(1); |
| 522 | } |
| 523 | redisReply *r = reply; |
| 524 | if (r->type == REDIS_REPLY_ERROR) { |
| 525 | /* Try to update slots configuration if reply error is |
| 526 | * MOVED/ASK/CLUSTERDOWN and the key(s) used by the command |
| 527 | * contain(s) the slot hash tag. |
| 528 | * If the error is not topology-update related then we |
| 529 | * immediately exit to avoid false results. */ |
| 530 | if (c->cluster_node && c->staglen) { |
| 531 | int fetch_slots = 0, do_wait = 0; |
| 532 | if (!strncmp(r->str,"MOVED",5) || !strncmp(r->str,"ASK",3)) |
| 533 | fetch_slots = 1; |
| 534 | else if (!strncmp(r->str,"CLUSTERDOWN",11)) { |
| 535 | /* Usually the cluster is able to recover itself after |
| 536 | * a CLUSTERDOWN error, so try to sleep one second |
| 537 | * before requesting the new configuration. */ |
| 538 | fetch_slots = 1; |
| 539 | do_wait = 1; |
| 540 | printf("Error from server %s:%d: %s.\n", |
| 541 | c->cluster_node->ip, |
| 542 | c->cluster_node->port, |
| 543 | r->str); |
| 544 | } |
| 545 | if (do_wait) sleep(1); |
| 546 | if (fetch_slots && !fetchClusterSlotsConfiguration(c)) |
| 547 | exit(1); |
| 548 | } else { |
| 549 | if (c->cluster_node) { |
| 550 | printf("Error from server %s:%d: %s\n", |
| 551 | c->cluster_node->ip, |
| 552 | c->cluster_node->port, |
| 553 | r->str); |
| 554 | } else printf("Error from server: %s\n", r->str); |
nothing calls this directly
no test coverage detected