blob: 235f21a4d3e6217359f53a6ec6c59f07e7e558a2 [file] [log] [blame]
Marc Slemko3ea00332006-08-17 01:11:13 +00001#include <concurrency/ThreadManager.h>
2#include <concurrency/PosixThreadFactory.h>
3#include <concurrency/Monitor.h>
4#include <concurrency/Util.h>
Mark Sleeb9ff32a2006-11-16 01:00:24 +00005#include <concurrency/Mutex.h>
Marc Slemko3ea00332006-08-17 01:11:13 +00006#include <protocol/TBinaryProtocol.h>
7#include <server/TSimpleServer.h>
8#include <server/TThreadPoolServer.h>
Mark Slee739dbe52007-02-01 22:55:30 +00009#include <server/TThreadedServer.h>
Marc Slemko3ea00332006-08-17 01:11:13 +000010#include <transport/TServerSocket.h>
11#include <transport/TSocket.h>
Mark Sleed7173472006-10-25 19:52:10 +000012#include <transport/TTransportUtils.h>
Aditya Agarwal25b29362006-12-09 00:58:15 +000013#include <transport/TFileTransport.h>
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000014#include <TLogging.h>
Aditya Agarwal3950f472006-10-11 02:50:15 +000015
16#include "Service.h"
Marc Slemko3ea00332006-08-17 01:11:13 +000017
18#include <iostream>
19#include <set>
20#include <stdexcept>
21#include <sstream>
22
Mark Sleeb9ff32a2006-11-16 01:00:24 +000023#include <map>
24#include <ext/hash_map>
25using __gnu_cxx::hash_map;
26using __gnu_cxx::hash;
27
Marc Slemko3ea00332006-08-17 01:11:13 +000028using namespace std;
29
30using namespace facebook::thrift;
31using namespace facebook::thrift::protocol;
32using namespace facebook::thrift::transport;
33using namespace facebook::thrift::server;
Mark Sleeb9ff32a2006-11-16 01:00:24 +000034using namespace facebook::thrift::concurrency;
Marc Slemko3ea00332006-08-17 01:11:13 +000035
36using namespace test::stress;
37
Mark Sleeb9ff32a2006-11-16 01:00:24 +000038struct eqstr {
39 bool operator()(const char* s1, const char* s2) const {
40 return strcmp(s1, s2) == 0;
41 }
42};
43
44struct ltstr {
45 bool operator()(const char* s1, const char* s2) const {
46 return strcmp(s1, s2) < 0;
47 }
48};
49
50
51// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
52typedef map<const char*, int, ltstr> count_map;
53
Aditya Agarwal3950f472006-10-11 02:50:15 +000054class Server : public ServiceIf {
Marc Slemko3ea00332006-08-17 01:11:13 +000055 public:
Mark Sleeb9ff32a2006-11-16 01:00:24 +000056 Server() {}
57
58 void count(const char* method) {
59 MutexMonitor m(lock_);
60 int ct = counts_[method];
61 counts_[method] = ++ct;
62 }
63
64 void echoVoid() {
65 count("echoVoid");
66 return;
67 }
68
69 count_map getCount() {
70 MutexMonitor m(lock_);
71 return counts_;
72 }
73
Mark Slee739dbe52007-02-01 22:55:30 +000074 int8_t echoByte(const int8_t arg) {return arg;}
75 int32_t echoI32(const int32_t arg) {return arg;}
76 int64_t echoI64(const int64_t arg) {return arg;}
77 void echoString(string& out, const string &arg) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000078 if (arg != "hello") {
79 T_ERROR_ABORT("WRONG STRING!!!!");
80 }
Mark Slee739dbe52007-02-01 22:55:30 +000081 out = arg;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000082 }
Mark Slee739dbe52007-02-01 22:55:30 +000083 void echoList(vector<int8_t> &out, const vector<int8_t> &arg) { out = arg; }
84 void echoSet(set<int8_t> &out, const set<int8_t> &arg) { out = arg; }
85 void echoMap(map<int8_t, int8_t> &out, const map<int8_t, int8_t> &arg) { out = arg; }
Mark Sleeb9ff32a2006-11-16 01:00:24 +000086
87private:
88 count_map counts_;
89 Mutex lock_;
90
Marc Slemko3ea00332006-08-17 01:11:13 +000091};
92
93class ClientThread: public Runnable {
94public:
95
Marc Slemkod97eb612006-08-24 23:37:36 +000096 ClientThread(shared_ptr<TTransport>transport, shared_ptr<ServiceClient> client, Monitor& monitor, size_t& workerCount, size_t loopCount, TType loopType) :
Marc Slemko3ea00332006-08-17 01:11:13 +000097 _transport(transport),
98 _client(client),
99 _monitor(monitor),
100 _workerCount(workerCount),
Marc Slemkod97eb612006-08-24 23:37:36 +0000101 _loopCount(loopCount),
102 _loopType(loopType)
Marc Slemko3ea00332006-08-17 01:11:13 +0000103 {}
104
105 void run() {
106
107 // Wait for all worker threads to start
108
109 {Synchronized s(_monitor);
110 while(_workerCount == 0) {
111 _monitor.wait();
112 }
113 }
114
115 _startTime = Util::currentTime();
116
117 _transport->open();
118
Marc Slemkod97eb612006-08-24 23:37:36 +0000119 switch(_loopType) {
120 case T_VOID: loopEchoVoid(); break;
121 case T_BYTE: loopEchoByte(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000122 case T_I32: loopEchoI32(); break;
123 case T_I64: loopEchoI64(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000124 case T_STRING: loopEchoString(); break;
125 default: cerr << "Unexpected loop type" << _loopType << endl; break;
Marc Slemko3ea00332006-08-17 01:11:13 +0000126 }
127
128 _endTime = Util::currentTime();
129
130 _transport->close();
131
132 _done = true;
133
134 {Synchronized s(_monitor);
135
136 _workerCount--;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000137
Marc Slemko3ea00332006-08-17 01:11:13 +0000138 if(_workerCount == 0) {
139
140 _monitor.notify();
141 }
142 }
143 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000144
145 void loopEchoVoid() {
146 for(size_t ix = 0; ix < _loopCount; ix++) {
147 _client->echoVoid();
148 }
149 }
150
151 void loopEchoByte() {
152 for(size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000153 int8_t arg = 1;
154 int8_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000155 result =_client->echoByte(arg);
156 assert(result == arg);
157 }
158 }
159
Marc Slemkod97eb612006-08-24 23:37:36 +0000160 void loopEchoI32() {
161 for(size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000162 int32_t arg = 1;
163 int32_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000164 result =_client->echoI32(arg);
165 assert(result == arg);
166 }
167 }
168
169 void loopEchoI64() {
170 for(size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000171 int64_t arg = 1;
172 int64_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000173 result =_client->echoI64(arg);
174 assert(result == arg);
175 }
176 }
Aditya Agarwal3950f472006-10-11 02:50:15 +0000177
Marc Slemkod97eb612006-08-24 23:37:36 +0000178 void loopEchoString() {
179 for(size_t ix = 0; ix < _loopCount; ix++) {
180 string arg = "hello";
181 string result;
Mark Slee739dbe52007-02-01 22:55:30 +0000182 _client->echoString(result, arg);
Marc Slemkod97eb612006-08-24 23:37:36 +0000183 assert(result == arg);
184 }
185 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000186
Marc Slemko3ea00332006-08-17 01:11:13 +0000187 shared_ptr<TTransport> _transport;
188 shared_ptr<ServiceClient> _client;
189 Monitor& _monitor;
190 size_t& _workerCount;
191 size_t _loopCount;
Marc Slemkod97eb612006-08-24 23:37:36 +0000192 TType _loopType;
Marc Slemko3ea00332006-08-17 01:11:13 +0000193 long long _startTime;
194 long long _endTime;
195 bool _done;
196 Monitor _sleep;
197};
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000198
199
Marc Slemko3ea00332006-08-17 01:11:13 +0000200int main(int argc, char **argv) {
201
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000202 int port = 9091;
Marc Slemko3ea00332006-08-17 01:11:13 +0000203 string serverType = "thread-pool";
204 string protocolType = "binary";
205 size_t workerCount = 4;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000206 size_t clientCount = 20;
207 size_t loopCount = 50000;
Marc Slemkod97eb612006-08-24 23:37:36 +0000208 TType loopType = T_VOID;
209 string callName = "echoVoid";
Marc Slemkob09f5882006-08-23 22:03:34 +0000210 bool runServer = true;
Aditya Agarwal3950f472006-10-11 02:50:15 +0000211 bool logRequests = false;
212 string requestLogPath = "./requestlog.tlog";
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000213 bool replayRequests = false;
Marc Slemko3ea00332006-08-17 01:11:13 +0000214
Marc Slemkob09f5882006-08-23 22:03:34 +0000215 ostringstream usage;
Marc Slemko3ea00332006-08-17 01:11:13 +0000216
217 usage <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000218 argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--clients=<client-count>] [--loop=<loop-count>]" << endl <<
219 "\tclients Number of client threads to create - 0 implies no clients, i.e. server only. Default is " << clientCount << endl <<
220 "\thelp Prints this help text." << endl <<
Marc Slemkod97eb612006-08-24 23:37:36 +0000221 "\tcall Service method to call. Default is " << callName << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000222 "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl <<
223 "\tport The port the server and clients should bind to for thrift network connections. Default is " << port << endl <<
224 "\tserver Run the Thrift server in this process. Default is " << runServer << endl <<
225 "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
226 "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
Aditya Agarwal3950f472006-10-11 02:50:15 +0000227 "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000228 "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000229 "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
Marc Slemko3ea00332006-08-17 01:11:13 +0000230
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000231
Marc Slemko3ea00332006-08-17 01:11:13 +0000232 map<string, string> args;
233
234 for(int ix = 1; ix < argc; ix++) {
235
236 string arg(argv[ix]);
237
238 if(arg.compare(0,2, "--") == 0) {
239
240 size_t end = arg.find_first_of("=", 2);
241
Marc Slemko056f9ba2006-08-17 02:59:05 +0000242 string key = string(arg, 2, end - 2);
243
Marc Slemko3ea00332006-08-17 01:11:13 +0000244 if(end != string::npos) {
Marc Slemko056f9ba2006-08-17 02:59:05 +0000245 args[key] = string(arg, end + 1);
Marc Slemko3ea00332006-08-17 01:11:13 +0000246 } else {
Marc Slemko056f9ba2006-08-17 02:59:05 +0000247 args[key] = "true";
Marc Slemko3ea00332006-08-17 01:11:13 +0000248 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000249 } else {
250 throw invalid_argument("Unexcepted command line token: "+arg);
251 }
252 }
253
254 try {
255
Marc Slemkob09f5882006-08-23 22:03:34 +0000256 if(!args["clients"].empty()) {
257 clientCount = atoi(args["clients"].c_str());
258 }
259
260 if(!args["help"].empty()) {
261 cerr << usage.str();
262 return 0;
263 }
264
265 if(!args["loop"].empty()) {
266 loopCount = atoi(args["loop"].c_str());
267 }
268
Marc Slemkod97eb612006-08-24 23:37:36 +0000269 if(!args["call"].empty()) {
270 callName = args["call"];
271 }
272
Marc Slemko3ea00332006-08-17 01:11:13 +0000273 if(!args["port"].empty()) {
274 port = atoi(args["port"].c_str());
275 }
276
Marc Slemkob09f5882006-08-23 22:03:34 +0000277 if(!args["server"].empty()) {
278 runServer = args["server"] == "true";
279 }
280
Aditya Agarwal3950f472006-10-11 02:50:15 +0000281 if(!args["log-request"].empty()) {
282 logRequests = args["log-request"] == "true";
283 }
284
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000285 if(!args["replay-request"].empty()) {
286 replayRequests = args["replay-request"] == "true";
287 }
288
Marc Slemko3ea00332006-08-17 01:11:13 +0000289 if(!args["server-type"].empty()) {
290 serverType = args["server-type"];
291
292 if(serverType == "simple") {
293
294 } else if(serverType == "thread-pool") {
295
Mark Slee739dbe52007-02-01 22:55:30 +0000296 } else if(serverType == "threaded") {
297
Marc Slemko3ea00332006-08-17 01:11:13 +0000298 } else {
299
300 throw invalid_argument("Unknown server type "+serverType);
301 }
302 }
303
304 if(!args["workers"].empty()) {
305 workerCount = atoi(args["workers"].c_str());
306 }
307
Marc Slemko3ea00332006-08-17 01:11:13 +0000308 } catch(exception& e) {
309 cerr << e.what() << endl;
310 cerr << usage;
311 }
312
Marc Slemko3ea00332006-08-17 01:11:13 +0000313 shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
314
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000315 // Dispatcher
316 shared_ptr<Server> serviceHandler(new Server());
Marc Slemko3ea00332006-08-17 01:11:13 +0000317
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000318 if (replayRequests) {
319 shared_ptr<Server> serviceHandler(new Server());
320 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
321
322 // Transports
323 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
324 fileTransport->setChunkSize(2 * 1024 * 1024);
325 fileTransport->setMaxEventSize(1024 * 16);
326 fileTransport->seekToEnd();
327
328 // Protocol Factory
329 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
330
331 TFileProcessor fileProcessor(serviceProcessor,
332 protocolFactory,
333 fileTransport);
334
335 fileProcessor.process(0, true);
336 exit(0);
337 }
338
339
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000340 if(runServer) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000341
Mark Sleed7173472006-10-25 19:52:10 +0000342 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Marc Slemko3ea00332006-08-17 01:11:13 +0000343
Marc Slemkob09f5882006-08-23 22:03:34 +0000344 // Transport
345 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Marc Slemko3ea00332006-08-17 01:11:13 +0000346
Aditya Agarwal3950f472006-10-11 02:50:15 +0000347 // Transport Factory
348 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
349
Mark Sleed7173472006-10-25 19:52:10 +0000350 // Protocol Factory
351 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000352
353 if (logRequests) {
354 // initialize the log file
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000355 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
356 fileTransport->setChunkSize(2 * 1024 * 1024);
357 fileTransport->setMaxEventSize(1024 * 16);
Aditya Agarwal3950f472006-10-11 02:50:15 +0000358
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000359 transportFactory =
Mark Slee79e41b82007-02-07 04:07:07 +0000360 shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Aditya Agarwal3950f472006-10-11 02:50:15 +0000361 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000362
Marc Slemkob09f5882006-08-23 22:03:34 +0000363 shared_ptr<Thread> serverThread;
Marc Slemko3ea00332006-08-17 01:11:13 +0000364
Marc Slemkob09f5882006-08-23 22:03:34 +0000365 if(serverType == "simple") {
366
Mark Sleed7173472006-10-25 19:52:10 +0000367 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000368
Mark Slee739dbe52007-02-01 22:55:30 +0000369 } else if (serverType == "threaded") {
370
371 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadedServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
372
Marc Slemkob09f5882006-08-23 22:03:34 +0000373 } else if(serverType == "thread-pool") {
374
375 shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
376
377 threadManager->threadFactory(threadFactory);
Mark Sleed7173472006-10-25 19:52:10 +0000378 threadManager->start();
379 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadPoolServer(serviceProcessor, serverSocket, transportFactory, protocolFactory, threadManager)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000380 }
381
382 cerr << "Starting the server on port " << port << endl;
383
384 serverThread->start();
385
386 // If we aren't running clients, just wait forever for external clients
387
Mark Sleed7173472006-10-25 19:52:10 +0000388 if (clientCount == 0) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000389 serverThread->join();
390 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000391 }
392
Mark Sleed7173472006-10-25 19:52:10 +0000393 if (clientCount > 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000394
Marc Slemkob09f5882006-08-23 22:03:34 +0000395 Monitor monitor;
Marc Slemko3ea00332006-08-17 01:11:13 +0000396
Marc Slemkob09f5882006-08-23 22:03:34 +0000397 size_t threadCount = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000398
Marc Slemkob09f5882006-08-23 22:03:34 +0000399 set<shared_ptr<Thread> > clientThreads;
Marc Slemko3ea00332006-08-17 01:11:13 +0000400
Marc Slemkod97eb612006-08-24 23:37:36 +0000401 if(callName == "echoVoid") { loopType = T_VOID;}
402 else if(callName == "echoByte") { loopType = T_BYTE;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000403 else if(callName == "echoI32") { loopType = T_I32;}
404 else if(callName == "echoI64") { loopType = T_I64;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000405 else if(callName == "echoString") { loopType = T_STRING;}
406 else {throw invalid_argument("Unknown service call "+callName);}
407
Marc Slemkob09f5882006-08-23 22:03:34 +0000408 for(size_t ix = 0; ix < clientCount; ix++) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000409
Marc Slemkob09f5882006-08-23 22:03:34 +0000410 shared_ptr<TSocket> socket(new TSocket("127.0.01", port));
411 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
Mark Slee739dbe52007-02-01 22:55:30 +0000412 shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
Mark Sleed7173472006-10-25 19:52:10 +0000413 shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
Marc Slemko3ea00332006-08-17 01:11:13 +0000414
Aditya Agarwal3950f472006-10-11 02:50:15 +0000415 clientThreads.insert(threadFactory->newThread(shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Marc Slemkob09f5882006-08-23 22:03:34 +0000416 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000417
Marc Slemkob09f5882006-08-23 22:03:34 +0000418 for(std::set<shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
419 (*thread)->start();
420 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000421
Marc Slemkob09f5882006-08-23 22:03:34 +0000422 long long time00;
423 long long time01;
Marc Slemko3ea00332006-08-17 01:11:13 +0000424
Marc Slemkob09f5882006-08-23 22:03:34 +0000425 {Synchronized s(monitor);
426 threadCount = clientCount;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000427
Marc Slemkob09f5882006-08-23 22:03:34 +0000428 cerr << "Launch "<< clientCount << " client threads" << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000429
Marc Slemkob09f5882006-08-23 22:03:34 +0000430 time00 = Util::currentTime();
Marc Slemko056f9ba2006-08-17 02:59:05 +0000431
Marc Slemkob09f5882006-08-23 22:03:34 +0000432 monitor.notifyAll();
433
434 while(threadCount > 0) {
435 monitor.wait();
436 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000437
Marc Slemkob09f5882006-08-23 22:03:34 +0000438 time01 = Util::currentTime();
Marc Slemko3ea00332006-08-17 01:11:13 +0000439 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000440
Marc Slemkob09f5882006-08-23 22:03:34 +0000441 long long firstTime = 9223372036854775807LL;
442 long long lastTime = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000443
Marc Slemkob09f5882006-08-23 22:03:34 +0000444 double averageTime = 0;
445 long long minTime = 9223372036854775807LL;
446 long long maxTime = 0;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000447
Marc Slemkob09f5882006-08-23 22:03:34 +0000448 for(set<shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
Marc Slemko056f9ba2006-08-17 02:59:05 +0000449
Marc Slemkob09f5882006-08-23 22:03:34 +0000450 shared_ptr<ClientThread> client = dynamic_pointer_cast<ClientThread>((*ix)->runnable());
Marc Slemko056f9ba2006-08-17 02:59:05 +0000451
Marc Slemkob09f5882006-08-23 22:03:34 +0000452 long long delta = client->_endTime - client->_startTime;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000453
Marc Slemkob09f5882006-08-23 22:03:34 +0000454 assert(delta > 0);
Marc Slemko056f9ba2006-08-17 02:59:05 +0000455
Marc Slemkob09f5882006-08-23 22:03:34 +0000456 if(client->_startTime < firstTime) {
457 firstTime = client->_startTime;
458 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000459
Marc Slemkob09f5882006-08-23 22:03:34 +0000460 if(client->_endTime > lastTime) {
461 lastTime = client->_endTime;
462 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000463
Marc Slemkob09f5882006-08-23 22:03:34 +0000464 if(delta < minTime) {
465 minTime = delta;
466 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000467
Marc Slemkob09f5882006-08-23 22:03:34 +0000468 if(delta > maxTime) {
469 maxTime = delta;
470 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000471
Marc Slemkob09f5882006-08-23 22:03:34 +0000472 averageTime+= delta;
473 }
474
475 averageTime /= clientCount;
476
477
478 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
479
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000480 count_map count = serviceHandler->getCount();
481 count_map::iterator iter;
482 for (iter = count.begin(); iter != count.end(); ++iter) {
483 printf("%s => %d\n", iter->first, iter->second);
484 }
Marc Slemkob09f5882006-08-23 22:03:34 +0000485 cerr << "done." << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000486 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000487
Marc Slemko3ea00332006-08-17 01:11:13 +0000488 return 0;
489}