blobslap_client.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /* Gearman server and library
  2. * Copyright (C) 2008 Brian Aker, Eric Day
  3. * All rights reserved.
  4. *
  5. * Use and distribution licensed under the BSD license. See
  6. * the COPYING file in the parent directory for full text.
  7. */
  8. /**
  9. * @file
  10. * @brief Blob slap client utility
  11. */
  12. #include <benchmark/benchmark.h>
  13. #include <stdio.h>
  14. #define BLOBSLAP_DEFAULT_NUM_TASKS 10
  15. #define BLOBSLAP_DEFAULT_BLOB_MIN_SIZE 0
  16. #define BLOBSLAP_DEFAULT_BLOB_MAX_SIZE 1024
  17. #define BLOBSLAP_BUFFER_SIZE 8192
  18. static gearman_return_t _created(gearman_task_st *task);
  19. static gearman_return_t _data(gearman_task_st *task);
  20. static gearman_return_t _status(gearman_task_st *task);
  21. static gearman_return_t _complete(gearman_task_st *task);
  22. static gearman_return_t _fail(gearman_task_st *task);
  23. static void _usage(char *name);
  24. int main(int argc, char *argv[])
  25. {
  26. gearman_benchmark_st benchmark;
  27. int c;
  28. char *host= NULL;
  29. in_port_t port= 0;
  30. const char *function= GEARMAN_BENCHMARK_DEFAULT_FUNCTION;
  31. uint32_t num_tasks= BLOBSLAP_DEFAULT_NUM_TASKS;
  32. size_t min_size= BLOBSLAP_DEFAULT_BLOB_MIN_SIZE;
  33. size_t max_size= BLOBSLAP_DEFAULT_BLOB_MAX_SIZE;
  34. uint32_t count= 1;
  35. gearman_client_st client;
  36. gearman_task_st *tasks;
  37. char *blob;
  38. benchmark_init(&benchmark);
  39. if (gearman_client_create(&client) == NULL)
  40. {
  41. fprintf(stderr, "Memory allocation failure on client creation\n");
  42. exit(1);
  43. }
  44. gearman_client_add_options(&client, GEARMAN_CLIENT_UNBUFFERED_RESULT);
  45. while ((c= getopt(argc, argv, "bc:f:h:m:M:n:p:s:v")) != -1)
  46. {
  47. switch(c)
  48. {
  49. case 'b':
  50. benchmark.background= true;
  51. break;
  52. case 'c':
  53. count= (uint32_t)atoi(optarg);
  54. break;
  55. case 'f':
  56. function= optarg;
  57. break;
  58. case 'h':
  59. {
  60. host= optarg;
  61. gearman_return_t ret= gearman_client_add_server(&client, host, port);
  62. if (ret != GEARMAN_SUCCESS)
  63. {
  64. fprintf(stderr, "gearman_client_add_server() -> %s\n", gearman_client_error(&client));
  65. exit(1);
  66. }
  67. }
  68. break;
  69. case 'm':
  70. min_size= (size_t)atoi(optarg);
  71. break;
  72. case 'M':
  73. max_size= (size_t)atoi(optarg);
  74. break;
  75. case 'n':
  76. num_tasks= (uint32_t)atoi(optarg);
  77. break;
  78. case 'p':
  79. port= (in_port_t)atoi(optarg);
  80. break;
  81. case 's':
  82. srand((unsigned int)atoi(optarg));
  83. break;
  84. case 'v':
  85. benchmark.verbose++;
  86. break;
  87. default:
  88. gearman_client_free(&client);
  89. _usage(argv[0]);
  90. exit(1);
  91. }
  92. }
  93. if (host == NULL)
  94. {
  95. gearman_return_t ret;
  96. ret= gearman_client_add_server(&client, NULL, port);
  97. if (ret != GEARMAN_SUCCESS)
  98. {
  99. fprintf(stderr, "gearman_client_add_server() -> %s\n", gearman_client_error(&client));
  100. exit(1);
  101. }
  102. }
  103. if (min_size > max_size)
  104. {
  105. fprintf(stderr, "Min data size must be smaller than max data size\n");
  106. exit(1);
  107. }
  108. if (num_tasks == 0)
  109. {
  110. fprintf(stderr, "Number of tasks must be larger than zero\n");
  111. exit(1);
  112. }
  113. tasks= malloc(num_tasks * sizeof(gearman_task_st));
  114. if (tasks == NULL)
  115. {
  116. fprintf(stderr, "Memory allocation failure on malloc\n");
  117. exit(1);
  118. }
  119. blob= malloc(max_size);
  120. if (blob == NULL)
  121. {
  122. fprintf(stderr, "Memory allocation failure on malloc\n");
  123. exit(1);
  124. }
  125. memset(blob, 'x', max_size);
  126. while (1)
  127. {
  128. for (uint32_t x= 0; x < num_tasks; x++)
  129. {
  130. size_t blob_size;
  131. if (min_size == max_size)
  132. {
  133. blob_size= max_size;
  134. }
  135. else
  136. {
  137. blob_size= (size_t)rand();
  138. if (max_size > RAND_MAX)
  139. blob_size*= (size_t)(rand() + 1);
  140. blob_size= (blob_size % (max_size - min_size)) + min_size;
  141. }
  142. const char *blob_ptr= blob_size ? blob : NULL;
  143. gearman_return_t ret;
  144. if (benchmark.background)
  145. {
  146. (void)gearman_client_add_task_background(&client, &(tasks[x]),
  147. &benchmark, function, NULL,
  148. (void *)blob_ptr, blob_size, &ret);
  149. }
  150. else
  151. {
  152. (void)gearman_client_add_task(&client, &(tasks[x]), &benchmark,
  153. function, NULL, (void *)blob_ptr, blob_size,
  154. &ret);
  155. }
  156. if (ret != GEARMAN_SUCCESS)
  157. {
  158. if (ret == GEARMAN_LOST_CONNECTION)
  159. continue;
  160. if (benchmark.background)
  161. {
  162. fprintf(stderr, "#%u gearman_client_add_task_background(%s) -> %s\n",
  163. x, gearman_strerror(ret),
  164. gearman_client_error(&client));
  165. }
  166. else
  167. {
  168. fprintf(stderr, "%u gearman_client_add_task(%s) -> %s\n",
  169. x, gearman_strerror(ret),
  170. gearman_client_error(&client));
  171. }
  172. exit(1);
  173. }
  174. }
  175. gearman_client_set_created_fn(&client, _created);
  176. gearman_client_set_data_fn(&client, _data);
  177. gearman_client_set_status_fn(&client, _status);
  178. gearman_client_set_complete_fn(&client, _complete);
  179. gearman_client_set_fail_fn(&client, _fail);
  180. gearman_return_t ret= gearman_client_run_tasks(&client);
  181. if (ret != GEARMAN_SUCCESS && ret != GEARMAN_LOST_CONNECTION)
  182. {
  183. fprintf(stderr, "gearman_client_run_tasks() -> %s\n", gearman_client_error(&client));
  184. exit(1);
  185. }
  186. for (uint32_t x= 0; x < num_tasks; x++)
  187. {
  188. gearman_task_free(&(tasks[x]));
  189. }
  190. if (count > 0)
  191. {
  192. count--;
  193. if (count == 0)
  194. break;
  195. }
  196. }
  197. free(blob);
  198. free(tasks);
  199. gearman_client_free(&client);
  200. fprintf(stderr, "Success\n");
  201. return 0;
  202. }
  203. static gearman_return_t _created(gearman_task_st *task)
  204. {
  205. gearman_benchmark_st *benchmark;
  206. benchmark= (gearman_benchmark_st *)gearman_task_context(task);
  207. if (benchmark->background && benchmark->verbose > 0)
  208. benchmark_check_time(benchmark);
  209. if (benchmark->verbose > 2)
  210. printf("Created: %s\n", gearman_task_job_handle(task));
  211. return GEARMAN_SUCCESS;
  212. }
  213. static gearman_return_t _status(gearman_task_st *task)
  214. {
  215. gearman_benchmark_st *benchmark;
  216. benchmark= (gearman_benchmark_st *)gearman_task_context(task);
  217. if (benchmark->verbose > 2)
  218. {
  219. printf("Status: %s (%u/%u)\n", gearman_task_job_handle(task),
  220. gearman_task_numerator(task), gearman_task_denominator(task));
  221. }
  222. return GEARMAN_SUCCESS;
  223. }
  224. static gearman_return_t _data(gearman_task_st *task)
  225. {
  226. gearman_benchmark_st *benchmark;
  227. char buffer[BLOBSLAP_BUFFER_SIZE];
  228. size_t size;
  229. gearman_return_t ret;
  230. benchmark= (gearman_benchmark_st *)gearman_task_context(task);
  231. while (1)
  232. {
  233. size= gearman_task_recv_data(task, buffer, BLOBSLAP_BUFFER_SIZE, &ret);
  234. if (ret != GEARMAN_SUCCESS)
  235. return ret;
  236. if (size == 0)
  237. break;
  238. }
  239. if (benchmark->verbose > 2)
  240. {
  241. printf("Data: %s %zu\n", gearman_task_job_handle(task),
  242. gearman_task_data_size(task));
  243. }
  244. return GEARMAN_SUCCESS;
  245. }
  246. static gearman_return_t _complete(gearman_task_st *task)
  247. {
  248. gearman_benchmark_st *benchmark;
  249. char buffer[BLOBSLAP_BUFFER_SIZE];
  250. size_t size;
  251. gearman_return_t ret;
  252. benchmark= (gearman_benchmark_st *)gearman_task_context(task);
  253. while (1)
  254. {
  255. size= gearman_task_recv_data(task, buffer, BLOBSLAP_BUFFER_SIZE, &ret);
  256. if (ret != GEARMAN_SUCCESS)
  257. return ret;
  258. if (size == 0)
  259. break;
  260. }
  261. if (benchmark->verbose > 0)
  262. benchmark_check_time(benchmark);
  263. if (benchmark->verbose > 1)
  264. {
  265. printf("Completed: %s %zu\n", gearman_task_job_handle(task),
  266. gearman_task_data_size(task));
  267. }
  268. return GEARMAN_SUCCESS;
  269. }
  270. static gearman_return_t _fail(gearman_task_st *task)
  271. {
  272. gearman_benchmark_st *benchmark;
  273. benchmark= (gearman_benchmark_st *)gearman_task_context(task);
  274. if (benchmark->verbose > 0)
  275. benchmark_check_time(benchmark);
  276. if (benchmark->verbose > 1)
  277. printf("Failed: %s\n", gearman_task_job_handle(task));
  278. return GEARMAN_SUCCESS;
  279. }
  280. static void _usage(char *name)
  281. {
  282. printf("\nusage: %s\n"
  283. "\t[-c count] [-f <function>] [-h <host>] [-m <min_size>]\n"
  284. "\t[-M <max_size>] [-n <num_tasks>] [-p <port>] [-s] [-v]\n\n", name);
  285. printf("\t-c <count> - number of times to run all tasks\n");
  286. printf("\t-f <function> - function name for tasks (default %s)\n",
  287. GEARMAN_BENCHMARK_DEFAULT_FUNCTION);
  288. printf("\t-h <host> - job server host, can specify many\n");
  289. printf("\t-m <min_size> - minimum blob size (default %d)\n",
  290. BLOBSLAP_DEFAULT_BLOB_MIN_SIZE);
  291. printf("\t-M <max_size> - maximum blob size (default %d)\n",
  292. BLOBSLAP_DEFAULT_BLOB_MAX_SIZE);
  293. printf("\t-n <num_tasks> - number of tasks to run at once (default %d)\n",
  294. BLOBSLAP_DEFAULT_NUM_TASKS);
  295. printf("\t-p <port> - job server port\n");
  296. printf("\t-s <seed> - seed random number for blobsize with <seed>\n");
  297. printf("\t-v - increase verbose level\n");
  298. }