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