blob: 8f161c05fa14a238d8d9b5b66cfce8dc669b8424 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meier49ff8b12012-04-13 09:12:31 +000020#include <thrift/concurrency/ThreadManager.h>
21#include <thrift/concurrency/PlatformThreadFactory.h>
22#include <thrift/concurrency/Monitor.h>
23#include <thrift/concurrency/Util.h>
24#include <thrift/concurrency/Mutex.h>
25#include <thrift/protocol/TBinaryProtocol.h>
26#include <thrift/server/TSimpleServer.h>
27#include <thrift/server/TThreadPoolServer.h>
28#include <thrift/server/TThreadedServer.h>
29#include <thrift/server/TNonblockingServer.h>
30#include <thrift/transport/TServerSocket.h>
31#include <thrift/transport/TSocket.h>
32#include <thrift/transport/TTransportUtils.h>
33#include <thrift/transport/TFileTransport.h>
Roger Meier33eaa0f2012-04-13 09:13:13 +000034#include <thrift/TLogging.h>
Mark Sleee02385b2007-06-09 01:21:16 +000035
36#include "Service.h"
37
38#include <boost/shared_ptr.hpp>
39
40#include <iostream>
41#include <set>
42#include <stdexcept>
43#include <sstream>
Mark Sleee02385b2007-06-09 01:21:16 +000044#include <map>
Jake Farrell5d02b802014-01-07 21:42:01 -050045#if _WIN32
Konrad Grochowski16a23a62014-11-13 15:33:38 +010046#include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050047#endif
Mark Sleee02385b2007-06-09 01:21:16 +000048
49using namespace std;
Mark Sleee02385b2007-06-09 01:21:16 +000050
T Jake Lucianib5e62212009-01-31 22:36:20 +000051using namespace apache::thrift;
52using namespace apache::thrift::protocol;
53using namespace apache::thrift::transport;
54using namespace apache::thrift::server;
55using namespace apache::thrift::concurrency;
Mark Sleee02385b2007-06-09 01:21:16 +000056
57using namespace test::stress;
58
59struct eqstr {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010060 bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) == 0; }
Mark Sleee02385b2007-06-09 01:21:16 +000061};
62
63struct ltstr {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010064 bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; }
Mark Sleee02385b2007-06-09 01:21:16 +000065};
66
Mark Sleee02385b2007-06-09 01:21:16 +000067// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
68typedef map<const char*, int, ltstr> count_map;
69
70class Server : public ServiceIf {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010071public:
Mark Sleee02385b2007-06-09 01:21:16 +000072 Server() {}
73
74 void count(const char* method) {
Mark Slee79b16942007-11-26 19:05:29 +000075 Guard m(lock_);
Mark Sleee02385b2007-06-09 01:21:16 +000076 int ct = counts_[method];
77 counts_[method] = ++ct;
78 }
79
80 void echoVoid() {
81 count("echoVoid");
Mark Slee3e5d2d72007-06-15 01:45:56 +000082 // Sleep to simulate work
Jake Farrell5d02b802014-01-07 21:42:01 -050083 THRIFT_SLEEP_USEC(1);
Mark Sleee02385b2007-06-09 01:21:16 +000084 return;
85 }
86
87 count_map getCount() {
Mark Slee79b16942007-11-26 19:05:29 +000088 Guard m(lock_);
Mark Sleee02385b2007-06-09 01:21:16 +000089 return counts_;
90 }
91
Konrad Grochowski16a23a62014-11-13 15:33:38 +010092 int8_t echoByte(const int8_t arg) { return arg; }
93 int32_t echoI32(const int32_t arg) { return arg; }
94 int64_t echoI64(const int64_t arg) { return arg; }
95 void echoString(string& out, const string& arg) {
Mark Sleee02385b2007-06-09 01:21:16 +000096 if (arg != "hello") {
Roger Meiera8cef6e2011-07-17 18:55:59 +000097 T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
Mark Sleee02385b2007-06-09 01:21:16 +000098 }
99 out = arg;
100 }
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100101 void echoList(vector<int8_t>& out, const vector<int8_t>& arg) { out = arg; }
102 void echoSet(set<int8_t>& out, const set<int8_t>& arg) { out = arg; }
103 void echoMap(map<int8_t, int8_t>& out, const map<int8_t, int8_t>& arg) { out = arg; }
Mark Sleee02385b2007-06-09 01:21:16 +0000104
105private:
106 count_map counts_;
107 Mutex lock_;
Mark Sleee02385b2007-06-09 01:21:16 +0000108};
109
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100110class ClientThread : public Runnable {
Mark Sleee02385b2007-06-09 01:21:16 +0000111public:
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100112 ClientThread(boost::shared_ptr<TTransport> transport,
113 boost::shared_ptr<ServiceClient> client,
114 Monitor& monitor,
115 size_t& workerCount,
116 size_t loopCount,
117 TType loopType)
118 : _transport(transport),
119 _client(client),
120 _monitor(monitor),
121 _workerCount(workerCount),
122 _loopCount(loopCount),
123 _loopType(loopType) {}
Mark Sleee02385b2007-06-09 01:21:16 +0000124
125 void run() {
126
127 // Wait for all worker threads to start
128
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100129 {
130 Synchronized s(_monitor);
131 while (_workerCount == 0) {
132 _monitor.wait();
133 }
Mark Sleee02385b2007-06-09 01:21:16 +0000134 }
135
136 _startTime = Util::currentTime();
137
138 _transport->open();
139
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100140 switch (_loopType) {
141 case T_VOID:
142 loopEchoVoid();
143 break;
144 case T_BYTE:
145 loopEchoByte();
146 break;
147 case T_I32:
148 loopEchoI32();
149 break;
150 case T_I64:
151 loopEchoI64();
152 break;
153 case T_STRING:
154 loopEchoString();
155 break;
156 default:
157 cerr << "Unexpected loop type" << _loopType << endl;
158 break;
Mark Sleee02385b2007-06-09 01:21:16 +0000159 }
160
161 _endTime = Util::currentTime();
162
163 _transport->close();
164
165 _done = true;
166
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100167 {
168 Synchronized s(_monitor);
Mark Sleee02385b2007-06-09 01:21:16 +0000169
170 _workerCount--;
171
Mark Slee3e5d2d72007-06-15 01:45:56 +0000172 if (_workerCount == 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000173
174 _monitor.notify();
175 }
176 }
177 }
178
179 void loopEchoVoid() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000180 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000181 _client->echoVoid();
182 }
183 }
184
185 void loopEchoByte() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000186 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000187 int8_t arg = 1;
188 int8_t result;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100189 result = _client->echoByte(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500190 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000191 assert(result == arg);
192 }
193 }
194
195 void loopEchoI32() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000196 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000197 int32_t arg = 1;
198 int32_t result;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100199 result = _client->echoI32(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500200 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000201 assert(result == arg);
202 }
203 }
204
205 void loopEchoI64() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000206 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000207 int64_t arg = 1;
208 int64_t result;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100209 result = _client->echoI64(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500210 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000211 assert(result == arg);
212 }
213 }
214
215 void loopEchoString() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000216 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000217 string arg = "hello";
218 string result;
219 _client->echoString(result, arg);
220 assert(result == arg);
221 }
222 }
223
Roger Meier611f90c2011-12-11 22:08:51 +0000224 boost::shared_ptr<TTransport> _transport;
225 boost::shared_ptr<ServiceClient> _client;
Mark Sleee02385b2007-06-09 01:21:16 +0000226 Monitor& _monitor;
227 size_t& _workerCount;
228 size_t _loopCount;
229 TType _loopType;
Roger Meier5f9614c2010-11-21 16:59:05 +0000230 int64_t _startTime;
231 int64_t _endTime;
Mark Sleee02385b2007-06-09 01:21:16 +0000232 bool _done;
233 Monitor _sleep;
234};
235
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100236int main(int argc, char** argv) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500237#if _WIN32
238 transport::TWinsockSingleton::create();
239#endif
Mark Sleee02385b2007-06-09 01:21:16 +0000240
241 int port = 9091;
242 string serverType = "simple";
243 string protocolType = "binary";
Jake Farrell5d02b802014-01-07 21:42:01 -0500244 uint32_t workerCount = 4;
245 uint32_t clientCount = 20;
246 uint32_t loopCount = 1000;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100247 TType loopType = T_VOID;
Mark Sleee02385b2007-06-09 01:21:16 +0000248 string callName = "echoVoid";
249 bool runServer = true;
250 bool logRequests = false;
251 string requestLogPath = "./requestlog.tlog";
252 bool replayRequests = false;
253
254 ostringstream usage;
255
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100256 usage << argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] "
257 "[--protocol-type=<protocol-type>] [--workers=<worker-count>] "
258 "[--clients=<client-count>] [--loop=<loop-count>]" << endl
259 << "\tclients Number of client threads to create - 0 implies no clients, i.e. "
260 "server only. Default is " << clientCount << endl
261 << "\thelp Prints this help text." << endl
262 << "\tcall Service method to call. Default is " << callName << endl
263 << "\tloop The number of remote thrift calls each client makes. Default is "
264 << loopCount << endl << "\tport The port the server and clients should bind to "
265 "for thrift network connections. Default is " << port << endl
266 << "\tserver Run the Thrift server in this process. Default is " << runServer
267 << endl << "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is "
268 << serverType << endl
269 << "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is "
270 << protocolType << endl
271 << "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests
272 << endl << "\treplay-request Replay requests from log file (./requestlog.tlog) Default is "
273 << replayRequests << endl << "\tworkers Number of thread pools workers. Only valid "
274 "for thread-pool server type. Default is " << workerCount
275 << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000276
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100277 map<string, string> args;
Mark Sleee02385b2007-06-09 01:21:16 +0000278
Mark Slee3e5d2d72007-06-15 01:45:56 +0000279 for (int ix = 1; ix < argc; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000280
281 string arg(argv[ix]);
282
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100283 if (arg.compare(0, 2, "--") == 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000284
285 size_t end = arg.find_first_of("=", 2);
286
287 string key = string(arg, 2, end - 2);
288
Mark Slee3e5d2d72007-06-15 01:45:56 +0000289 if (end != string::npos) {
Mark Sleee02385b2007-06-09 01:21:16 +0000290 args[key] = string(arg, end + 1);
291 } else {
292 args[key] = "true";
293 }
294 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100295 throw invalid_argument("Unexcepted command line token: " + arg);
Mark Sleee02385b2007-06-09 01:21:16 +0000296 }
297 }
298
299 try {
300
Mark Slee3e5d2d72007-06-15 01:45:56 +0000301 if (!args["clients"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000302 clientCount = atoi(args["clients"].c_str());
303 }
304
Mark Slee3e5d2d72007-06-15 01:45:56 +0000305 if (!args["help"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000306 cerr << usage.str();
307 return 0;
308 }
309
Mark Slee3e5d2d72007-06-15 01:45:56 +0000310 if (!args["loop"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000311 loopCount = atoi(args["loop"].c_str());
312 }
313
Mark Slee3e5d2d72007-06-15 01:45:56 +0000314 if (!args["call"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000315 callName = args["call"];
316 }
317
Mark Slee3e5d2d72007-06-15 01:45:56 +0000318 if (!args["port"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000319 port = atoi(args["port"].c_str());
320 }
321
Mark Slee3e5d2d72007-06-15 01:45:56 +0000322 if (!args["server"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000323 runServer = args["server"] == "true";
324 }
325
Mark Slee3e5d2d72007-06-15 01:45:56 +0000326 if (!args["log-request"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000327 logRequests = args["log-request"] == "true";
328 }
329
Mark Slee3e5d2d72007-06-15 01:45:56 +0000330 if (!args["replay-request"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000331 replayRequests = args["replay-request"] == "true";
332 }
333
Mark Slee3e5d2d72007-06-15 01:45:56 +0000334 if (!args["server-type"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000335 serverType = args["server-type"];
336 }
337
Mark Slee3e5d2d72007-06-15 01:45:56 +0000338 if (!args["workers"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000339 workerCount = atoi(args["workers"].c_str());
340 }
341
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100342 } catch (std::exception& e) {
Mark Sleee02385b2007-06-09 01:21:16 +0000343 cerr << e.what() << endl;
Jake Farrell5d02b802014-01-07 21:42:01 -0500344 cerr << usage.str();
Mark Sleee02385b2007-06-09 01:21:16 +0000345 }
346
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100347 boost::shared_ptr<PlatformThreadFactory> threadFactory
348 = boost::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000349
350 // Dispatcher
Roger Meier611f90c2011-12-11 22:08:51 +0000351 boost::shared_ptr<Server> serviceHandler(new Server());
Mark Sleee02385b2007-06-09 01:21:16 +0000352
353 if (replayRequests) {
Roger Meier611f90c2011-12-11 22:08:51 +0000354 boost::shared_ptr<Server> serviceHandler(new Server());
355 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Mark Sleee02385b2007-06-09 01:21:16 +0000356
357 // Transports
Roger Meier611f90c2011-12-11 22:08:51 +0000358 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Mark Sleee02385b2007-06-09 01:21:16 +0000359 fileTransport->setChunkSize(2 * 1024 * 1024);
360 fileTransport->setMaxEventSize(1024 * 16);
361 fileTransport->seekToEnd();
362
363 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000364 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000365
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100366 TFileProcessor fileProcessor(serviceProcessor, protocolFactory, fileTransport);
Mark Sleee02385b2007-06-09 01:21:16 +0000367
368 fileProcessor.process(0, true);
369 exit(0);
370 }
371
Mark Slee3e5d2d72007-06-15 01:45:56 +0000372 if (runServer) {
Mark Sleee02385b2007-06-09 01:21:16 +0000373
Roger Meier611f90c2011-12-11 22:08:51 +0000374 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Mark Sleee02385b2007-06-09 01:21:16 +0000375
376 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000377 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000378
379 // Transport Factory
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100380 boost::shared_ptr<TTransportFactory> transportFactory;
Mark Sleee02385b2007-06-09 01:21:16 +0000381
382 if (logRequests) {
383 // initialize the log file
Roger Meier611f90c2011-12-11 22:08:51 +0000384 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Mark Sleee02385b2007-06-09 01:21:16 +0000385 fileTransport->setChunkSize(2 * 1024 * 1024);
386 fileTransport->setMaxEventSize(1024 * 16);
387
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100388 transportFactory
389 = boost::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Mark Sleee02385b2007-06-09 01:21:16 +0000390 }
391
Roger Meier611f90c2011-12-11 22:08:51 +0000392 boost::shared_ptr<Thread> serverThread;
393 boost::shared_ptr<Thread> serverThread2;
Mark Sleee02385b2007-06-09 01:21:16 +0000394
Mark Slee3e5d2d72007-06-15 01:45:56 +0000395 if (serverType == "simple") {
Mark Sleee02385b2007-06-09 01:21:16 +0000396
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100397 serverThread = threadFactory->newThread(boost::shared_ptr<TServer>(
398 new TNonblockingServer(serviceProcessor, protocolFactory, port)));
399 serverThread2 = threadFactory->newThread(boost::shared_ptr<TServer>(
400 new TNonblockingServer(serviceProcessor, protocolFactory, port + 1)));
Mark Sleee02385b2007-06-09 01:21:16 +0000401
Mark Slee3e5d2d72007-06-15 01:45:56 +0000402 } else if (serverType == "thread-pool") {
Mark Sleee02385b2007-06-09 01:21:16 +0000403
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100404 boost::shared_ptr<ThreadManager> threadManager
405 = ThreadManager::newSimpleThreadManager(workerCount);
Mark Sleee02385b2007-06-09 01:21:16 +0000406
407 threadManager->threadFactory(threadFactory);
408 threadManager->start();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100409 serverThread = threadFactory->newThread(boost::shared_ptr<TServer>(
410 new TNonblockingServer(serviceProcessor, protocolFactory, port, threadManager)));
411 serverThread2 = threadFactory->newThread(boost::shared_ptr<TServer>(
412 new TNonblockingServer(serviceProcessor, protocolFactory, port + 1, threadManager)));
Mark Sleee02385b2007-06-09 01:21:16 +0000413 }
414
Mark Slee79b16942007-11-26 19:05:29 +0000415 cerr << "Starting the server on port " << port << " and " << (port + 1) << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000416 serverThread->start();
Mark Slee79b16942007-11-26 19:05:29 +0000417 serverThread2->start();
Mark Sleee02385b2007-06-09 01:21:16 +0000418
419 // If we aren't running clients, just wait forever for external clients
420
421 if (clientCount == 0) {
422 serverThread->join();
Mark Slee79b16942007-11-26 19:05:29 +0000423 serverThread2->join();
Mark Sleee02385b2007-06-09 01:21:16 +0000424 }
425 }
Jake Farrell5d02b802014-01-07 21:42:01 -0500426 THRIFT_SLEEP_SEC(1);
Mark Sleee02385b2007-06-09 01:21:16 +0000427
428 if (clientCount > 0) {
429
430 Monitor monitor;
431
432 size_t threadCount = 0;
433
Roger Meier611f90c2011-12-11 22:08:51 +0000434 set<boost::shared_ptr<Thread> > clientThreads;
Mark Sleee02385b2007-06-09 01:21:16 +0000435
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100436 if (callName == "echoVoid") {
437 loopType = T_VOID;
438 } else if (callName == "echoByte") {
439 loopType = T_BYTE;
440 } else if (callName == "echoI32") {
441 loopType = T_I32;
442 } else if (callName == "echoI64") {
443 loopType = T_I64;
444 } else if (callName == "echoString") {
445 loopType = T_STRING;
446 } else {
447 throw invalid_argument("Unknown service call " + callName);
448 }
Mark Sleee02385b2007-06-09 01:21:16 +0000449
Jake Farrell5d02b802014-01-07 21:42:01 -0500450 for (uint32_t ix = 0; ix < clientCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000451
Roger Meier611f90c2011-12-11 22:08:51 +0000452 boost::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port + (ix % 2)));
453 boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
454 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(framedSocket));
455 boost::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
Mark Sleee02385b2007-06-09 01:21:16 +0000456
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100457 clientThreads.insert(threadFactory->newThread(boost::shared_ptr<ClientThread>(
458 new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Mark Sleee02385b2007-06-09 01:21:16 +0000459 }
460
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100461 for (std::set<boost::shared_ptr<Thread> >::const_iterator thread = clientThreads.begin();
462 thread != clientThreads.end();
463 thread++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000464 (*thread)->start();
465 }
466
Roger Meier5f9614c2010-11-21 16:59:05 +0000467 int64_t time00;
468 int64_t time01;
Mark Sleee02385b2007-06-09 01:21:16 +0000469
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100470 {
471 Synchronized s(monitor);
Mark Sleee02385b2007-06-09 01:21:16 +0000472 threadCount = clientCount;
473
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100474 cerr << "Launch " << clientCount << " client threads" << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000475
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100476 time00 = Util::currentTime();
Mark Sleee02385b2007-06-09 01:21:16 +0000477
478 monitor.notifyAll();
479
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100480 while (threadCount > 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000481 monitor.wait();
482 }
483
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100484 time01 = Util::currentTime();
Mark Sleee02385b2007-06-09 01:21:16 +0000485 }
486
Roger Meier5f9614c2010-11-21 16:59:05 +0000487 int64_t firstTime = 9223372036854775807LL;
488 int64_t lastTime = 0;
Mark Sleee02385b2007-06-09 01:21:16 +0000489
490 double averageTime = 0;
Roger Meier5f9614c2010-11-21 16:59:05 +0000491 int64_t minTime = 9223372036854775807LL;
492 int64_t maxTime = 0;
Mark Sleee02385b2007-06-09 01:21:16 +0000493
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100494 for (set<boost::shared_ptr<Thread> >::iterator ix = clientThreads.begin();
495 ix != clientThreads.end();
496 ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000497
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100498 boost::shared_ptr<ClientThread> client
499 = boost::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
Mark Sleee02385b2007-06-09 01:21:16 +0000500
Roger Meier5f9614c2010-11-21 16:59:05 +0000501 int64_t delta = client->_endTime - client->_startTime;
Mark Sleee02385b2007-06-09 01:21:16 +0000502
503 assert(delta > 0);
504
Mark Slee3e5d2d72007-06-15 01:45:56 +0000505 if (client->_startTime < firstTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000506 firstTime = client->_startTime;
507 }
508
Mark Slee3e5d2d72007-06-15 01:45:56 +0000509 if (client->_endTime > lastTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000510 lastTime = client->_endTime;
511 }
512
Mark Slee3e5d2d72007-06-15 01:45:56 +0000513 if (delta < minTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000514 minTime = delta;
515 }
516
Mark Slee3e5d2d72007-06-15 01:45:56 +0000517 if (delta > maxTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000518 maxTime = delta;
519 }
520
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100521 averageTime += delta;
Mark Sleee02385b2007-06-09 01:21:16 +0000522 }
523
524 averageTime /= clientCount;
525
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100526 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount
527 << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000528
529 count_map count = serviceHandler->getCount();
530 count_map::iterator iter;
531 for (iter = count.begin(); iter != count.end(); ++iter) {
532 printf("%s => %d\n", iter->first, iter->second);
533 }
534 cerr << "done." << endl;
535 }
536
537 return 0;
538}