Create a benchmark client, configured to send the command passed as 'cmd' of * 'len' bytes. * * The command is copied N times in the client output buffer (that is reused * again and again to send the request to the server) accordingly to the configured * pipeline size. * * Also an initial SELECT command is prepended in order to make sure the right * database is selected, if needed. The ini
| 675 | * |
| 676 | * Even when cloning another client, prefix commands are applied if needed.*/ |
| 677 | static client createClient(char *cmd, size_t len, client from, int thread_id) { |
| 678 | int j; |
| 679 | int is_cluster_client = (config.cluster_mode && thread_id >= 0); |
| 680 | client c = zmalloc(sizeof(struct _client)); |
| 681 | |
| 682 | const char *ip = NULL; |
| 683 | int port = 0; |
| 684 | c->cluster_node = NULL; |
| 685 | if (config.hostsocket == NULL || is_cluster_client) { |
| 686 | if (!is_cluster_client) { |
| 687 | ip = config.hostip; |
| 688 | port = config.hostport; |
| 689 | } else { |
| 690 | int node_idx = 0; |
| 691 | if (config.num_threads < config.cluster_node_count) |
| 692 | node_idx = config.liveclients % config.cluster_node_count; |
| 693 | else |
| 694 | node_idx = thread_id % config.cluster_node_count; |
| 695 | clusterNode *node = config.cluster_nodes[node_idx]; |
| 696 | assert(node != NULL); |
| 697 | ip = (const char *) node->ip; |
| 698 | port = node->port; |
| 699 | c->cluster_node = node; |
| 700 | } |
| 701 | c->context = redisConnectNonBlock(ip,port); |
| 702 | } else { |
| 703 | c->context = redisConnectUnixNonBlock(config.hostsocket); |
| 704 | } |
| 705 | if (c->context->err) { |
| 706 | fprintf(stderr,"Could not connect to Redis at "); |
| 707 | if (config.hostsocket == NULL || is_cluster_client) |
| 708 | fprintf(stderr,"%s:%d: %s\n",ip,port,c->context->errstr); |
| 709 | else |
| 710 | fprintf(stderr,"%s: %s\n",config.hostsocket,c->context->errstr); |
| 711 | exit(1); |
| 712 | } |
| 713 | if (config.tls==1) { |
| 714 | const char *err = NULL; |
| 715 | if (cliSecureConnection(c->context, config.sslconfig, &err) == REDIS_ERR && err) { |
| 716 | fprintf(stderr, "Could not negotiate a TLS connection: %s\n", err); |
| 717 | exit(1); |
| 718 | } |
| 719 | } |
| 720 | c->thread_id = thread_id; |
| 721 | /* Suppress hiredis cleanup of unused buffers for max speed. */ |
| 722 | c->context->reader->maxbuf = 0; |
| 723 | |
| 724 | /* Build the request buffer: |
| 725 | * Queue N requests accordingly to the pipeline size, or simply clone |
| 726 | * the example client buffer. */ |
| 727 | c->obuf = sdsempty(); |
| 728 | /* Prefix the request buffer with AUTH and/or SELECT commands, if applicable. |
| 729 | * These commands are discarded after the first response, so if the client is |
| 730 | * reused the commands will not be used again. */ |
| 731 | c->prefix_pending = 0; |
| 732 | if (config.auth) { |
| 733 | char *buf = NULL; |
| 734 | int len; |
no test coverage detected