blob: 47ae671b0bd43598517cd189567ede69fdfd27d9 [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>
9#include <transport/TServerSocket.h>
10#include <transport/TSocket.h>
Mark Sleed7173472006-10-25 19:52:10 +000011#include <transport/TTransportUtils.h>
Aditya Agarwal3950f472006-10-11 02:50:15 +000012#include <transport/TBufferedRouterTransport.h>
Aditya Agarwal3950f472006-10-11 02:50:15 +000013#include <transport/TBufferedFileWriter.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
Aditya Agarwal3950f472006-10-11 02:50:15 +000074 int8_t echoByte(int8_t arg) {return arg;}
Marc Slemkod97eb612006-08-24 23:37:36 +000075 int32_t echoI32(int32_t arg) {return arg;}
76 int64_t echoI64(int64_t arg) {return arg;}
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000077 string echoString(string arg) {
78 if (arg != "hello") {
79 T_ERROR_ABORT("WRONG STRING!!!!");
80 }
81 return arg;
82 }
Aditya Agarwal3950f472006-10-11 02:50:15 +000083 vector<int8_t> echoList(vector<int8_t> arg) {return arg;}
84 set<int8_t> echoSet(set<int8_t> arg) {return arg;}
85 map<int8_t, int8_t> echoMap(map<int8_t, int8_t> arg) {return 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;
182 result =_client->echoString(arg);
183 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
296 } else {
297
298 throw invalid_argument("Unknown server type "+serverType);
299 }
300 }
301
302 if(!args["workers"].empty()) {
303 workerCount = atoi(args["workers"].c_str());
304 }
305
Marc Slemko3ea00332006-08-17 01:11:13 +0000306 } catch(exception& e) {
307 cerr << e.what() << endl;
308 cerr << usage;
309 }
310
Marc Slemko3ea00332006-08-17 01:11:13 +0000311 shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
312
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000313 // Dispatcher
314 shared_ptr<Server> serviceHandler(new Server());
Marc Slemko3ea00332006-08-17 01:11:13 +0000315
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000316 if (replayRequests) {
317 shared_ptr<Server> serviceHandler(new Server());
318 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
319
320 // Transports
321 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
322 fileTransport->setChunkSize(2 * 1024 * 1024);
323 fileTransport->setMaxEventSize(1024 * 16);
324 fileTransport->seekToEnd();
325
326 // Protocol Factory
327 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
328
329 TFileProcessor fileProcessor(serviceProcessor,
330 protocolFactory,
331 fileTransport);
332
333 fileProcessor.process(0, true);
334 exit(0);
335 }
336
337
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000338 if(runServer) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000339
Mark Sleed7173472006-10-25 19:52:10 +0000340 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Marc Slemko3ea00332006-08-17 01:11:13 +0000341
Marc Slemkob09f5882006-08-23 22:03:34 +0000342 // Transport
343 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Marc Slemko3ea00332006-08-17 01:11:13 +0000344
Aditya Agarwal3950f472006-10-11 02:50:15 +0000345 // Transport Factory
346 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
347
Mark Sleed7173472006-10-25 19:52:10 +0000348 // Protocol Factory
349 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000350
351 if (logRequests) {
352 // initialize the log file
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000353 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
354 fileTransport->setChunkSize(2 * 1024 * 1024);
355 fileTransport->setMaxEventSize(1024 * 16);
Aditya Agarwal3950f472006-10-11 02:50:15 +0000356
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000357 transportFactory =
358 shared_ptr<TTransportFactory>(new TBufferedRouterTransportFactory(fileTransport));
Aditya Agarwal3950f472006-10-11 02:50:15 +0000359 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000360
Marc Slemkob09f5882006-08-23 22:03:34 +0000361 shared_ptr<Thread> serverThread;
Marc Slemko3ea00332006-08-17 01:11:13 +0000362
Marc Slemkob09f5882006-08-23 22:03:34 +0000363 if(serverType == "simple") {
364
Mark Sleed7173472006-10-25 19:52:10 +0000365 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000366
367 } else if(serverType == "thread-pool") {
368
369 shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
370
371 threadManager->threadFactory(threadFactory);
Mark Sleed7173472006-10-25 19:52:10 +0000372 threadManager->start();
373 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadPoolServer(serviceProcessor, serverSocket, transportFactory, protocolFactory, threadManager)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000374 }
375
376 cerr << "Starting the server on port " << port << endl;
377
378 serverThread->start();
379
380 // If we aren't running clients, just wait forever for external clients
381
Mark Sleed7173472006-10-25 19:52:10 +0000382 if (clientCount == 0) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000383 serverThread->join();
384 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000385 }
386
Mark Sleed7173472006-10-25 19:52:10 +0000387 if (clientCount > 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000388
Marc Slemkob09f5882006-08-23 22:03:34 +0000389 Monitor monitor;
Marc Slemko3ea00332006-08-17 01:11:13 +0000390
Marc Slemkob09f5882006-08-23 22:03:34 +0000391 size_t threadCount = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000392
Marc Slemkob09f5882006-08-23 22:03:34 +0000393 set<shared_ptr<Thread> > clientThreads;
Marc Slemko3ea00332006-08-17 01:11:13 +0000394
Marc Slemkod97eb612006-08-24 23:37:36 +0000395 if(callName == "echoVoid") { loopType = T_VOID;}
396 else if(callName == "echoByte") { loopType = T_BYTE;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000397 else if(callName == "echoI32") { loopType = T_I32;}
398 else if(callName == "echoI64") { loopType = T_I64;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000399 else if(callName == "echoString") { loopType = T_STRING;}
400 else {throw invalid_argument("Unknown service call "+callName);}
401
Marc Slemkob09f5882006-08-23 22:03:34 +0000402 for(size_t ix = 0; ix < clientCount; ix++) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000403
Marc Slemkob09f5882006-08-23 22:03:34 +0000404 shared_ptr<TSocket> socket(new TSocket("127.0.01", port));
405 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
Mark Sleed7173472006-10-25 19:52:10 +0000406 shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket, bufferedSocket));
407 shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
Marc Slemko3ea00332006-08-17 01:11:13 +0000408
Aditya Agarwal3950f472006-10-11 02:50:15 +0000409 clientThreads.insert(threadFactory->newThread(shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Marc Slemkob09f5882006-08-23 22:03:34 +0000410 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000411
Marc Slemkob09f5882006-08-23 22:03:34 +0000412 for(std::set<shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
413 (*thread)->start();
414 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000415
Marc Slemkob09f5882006-08-23 22:03:34 +0000416 long long time00;
417 long long time01;
Marc Slemko3ea00332006-08-17 01:11:13 +0000418
Marc Slemkob09f5882006-08-23 22:03:34 +0000419 {Synchronized s(monitor);
420 threadCount = clientCount;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000421
Marc Slemkob09f5882006-08-23 22:03:34 +0000422 cerr << "Launch "<< clientCount << " client threads" << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000423
Marc Slemkob09f5882006-08-23 22:03:34 +0000424 time00 = Util::currentTime();
Marc Slemko056f9ba2006-08-17 02:59:05 +0000425
Marc Slemkob09f5882006-08-23 22:03:34 +0000426 monitor.notifyAll();
427
428 while(threadCount > 0) {
429 monitor.wait();
430 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000431
Marc Slemkob09f5882006-08-23 22:03:34 +0000432 time01 = Util::currentTime();
Marc Slemko3ea00332006-08-17 01:11:13 +0000433 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000434
Marc Slemkob09f5882006-08-23 22:03:34 +0000435 long long firstTime = 9223372036854775807LL;
436 long long lastTime = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000437
Marc Slemkob09f5882006-08-23 22:03:34 +0000438 double averageTime = 0;
439 long long minTime = 9223372036854775807LL;
440 long long maxTime = 0;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000441
Marc Slemkob09f5882006-08-23 22:03:34 +0000442 for(set<shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
Marc Slemko056f9ba2006-08-17 02:59:05 +0000443
Marc Slemkob09f5882006-08-23 22:03:34 +0000444 shared_ptr<ClientThread> client = dynamic_pointer_cast<ClientThread>((*ix)->runnable());
Marc Slemko056f9ba2006-08-17 02:59:05 +0000445
Marc Slemkob09f5882006-08-23 22:03:34 +0000446 long long delta = client->_endTime - client->_startTime;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000447
Marc Slemkob09f5882006-08-23 22:03:34 +0000448 assert(delta > 0);
Marc Slemko056f9ba2006-08-17 02:59:05 +0000449
Marc Slemkob09f5882006-08-23 22:03:34 +0000450 if(client->_startTime < firstTime) {
451 firstTime = client->_startTime;
452 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000453
Marc Slemkob09f5882006-08-23 22:03:34 +0000454 if(client->_endTime > lastTime) {
455 lastTime = client->_endTime;
456 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000457
Marc Slemkob09f5882006-08-23 22:03:34 +0000458 if(delta < minTime) {
459 minTime = delta;
460 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000461
Marc Slemkob09f5882006-08-23 22:03:34 +0000462 if(delta > maxTime) {
463 maxTime = delta;
464 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000465
Marc Slemkob09f5882006-08-23 22:03:34 +0000466 averageTime+= delta;
467 }
468
469 averageTime /= clientCount;
470
471
472 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
473
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000474 count_map count = serviceHandler->getCount();
475 count_map::iterator iter;
476 for (iter = count.begin(); iter != count.end(); ++iter) {
477 printf("%s => %d\n", iter->first, iter->second);
478 }
Marc Slemkob09f5882006-08-23 22:03:34 +0000479 cerr << "done." << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000480 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000481
Marc Slemko3ea00332006-08-17 01:11:13 +0000482 return 0;
483}