blob: 2aad4d60feed4ac2b24ff51c360626f4c0823011 [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
Marc Slemko3ea00332006-08-17 01:11:13 +000020#include <concurrency/ThreadManager.h>
21#include <concurrency/PosixThreadFactory.h>
22#include <concurrency/Monitor.h>
23#include <concurrency/Util.h>
Mark Sleeb9ff32a2006-11-16 01:00:24 +000024#include <concurrency/Mutex.h>
Marc Slemko3ea00332006-08-17 01:11:13 +000025#include <protocol/TBinaryProtocol.h>
26#include <server/TSimpleServer.h>
27#include <server/TThreadPoolServer.h>
Mark Slee739dbe52007-02-01 22:55:30 +000028#include <server/TThreadedServer.h>
Marc Slemko3ea00332006-08-17 01:11:13 +000029#include <transport/TServerSocket.h>
30#include <transport/TSocket.h>
Mark Sleed7173472006-10-25 19:52:10 +000031#include <transport/TTransportUtils.h>
Aditya Agarwal25b29362006-12-09 00:58:15 +000032#include <transport/TFileTransport.h>
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000033#include <TLogging.h>
Aditya Agarwal3950f472006-10-11 02:50:15 +000034
35#include "Service.h"
Marc Slemko3ea00332006-08-17 01:11:13 +000036
37#include <iostream>
38#include <set>
39#include <stdexcept>
40#include <sstream>
41
Mark Sleeb9ff32a2006-11-16 01:00:24 +000042#include <map>
43#include <ext/hash_map>
44using __gnu_cxx::hash_map;
45using __gnu_cxx::hash;
46
Marc Slemko3ea00332006-08-17 01:11:13 +000047using namespace std;
Mark Sleef4f18ec2007-05-16 21:22:34 +000048using namespace boost;
Marc Slemko3ea00332006-08-17 01:11:13 +000049
T Jake Lucianib5e62212009-01-31 22:36:20 +000050using namespace apache::thrift;
51using namespace apache::thrift::protocol;
52using namespace apache::thrift::transport;
53using namespace apache::thrift::server;
54using namespace apache::thrift::concurrency;
Marc Slemko3ea00332006-08-17 01:11:13 +000055
56using namespace test::stress;
57
Mark Sleeb9ff32a2006-11-16 01:00:24 +000058struct eqstr {
59 bool operator()(const char* s1, const char* s2) const {
60 return strcmp(s1, s2) == 0;
61 }
62};
63
64struct ltstr {
65 bool operator()(const char* s1, const char* s2) const {
66 return strcmp(s1, s2) < 0;
67 }
68};
69
70
David Reiss0c90f6f2008-02-06 22:18:40 +000071// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
72typedef map<const char*, int, ltstr> count_map;
Mark Sleeb9ff32a2006-11-16 01:00:24 +000073
Aditya Agarwal3950f472006-10-11 02:50:15 +000074class Server : public ServiceIf {
Marc Slemko3ea00332006-08-17 01:11:13 +000075 public:
Mark Sleeb9ff32a2006-11-16 01:00:24 +000076 Server() {}
77
78 void count(const char* method) {
David Reiss46379902008-02-04 19:23:57 +000079 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000080 int ct = counts_[method];
81 counts_[method] = ++ct;
82 }
83
84 void echoVoid() {
85 count("echoVoid");
86 return;
87 }
88
89 count_map getCount() {
David Reiss46379902008-02-04 19:23:57 +000090 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000091 return counts_;
92 }
93
Mark Slee739dbe52007-02-01 22:55:30 +000094 int8_t echoByte(const int8_t arg) {return arg;}
95 int32_t echoI32(const int32_t arg) {return arg;}
96 int64_t echoI64(const int64_t arg) {return arg;}
97 void echoString(string& out, const string &arg) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000098 if (arg != "hello") {
99 T_ERROR_ABORT("WRONG STRING!!!!");
100 }
Mark Slee739dbe52007-02-01 22:55:30 +0000101 out = arg;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000102 }
Mark Slee739dbe52007-02-01 22:55:30 +0000103 void echoList(vector<int8_t> &out, const vector<int8_t> &arg) { out = arg; }
104 void echoSet(set<int8_t> &out, const set<int8_t> &arg) { out = arg; }
105 void echoMap(map<int8_t, int8_t> &out, const map<int8_t, int8_t> &arg) { out = arg; }
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000106
107private:
108 count_map counts_;
109 Mutex lock_;
110
Marc Slemko3ea00332006-08-17 01:11:13 +0000111};
112
113class ClientThread: public Runnable {
114public:
115
Marc Slemkod97eb612006-08-24 23:37:36 +0000116 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 +0000117 _transport(transport),
118 _client(client),
119 _monitor(monitor),
120 _workerCount(workerCount),
Marc Slemkod97eb612006-08-24 23:37:36 +0000121 _loopCount(loopCount),
122 _loopType(loopType)
Marc Slemko3ea00332006-08-17 01:11:13 +0000123 {}
124
125 void run() {
126
David Reiss0c90f6f2008-02-06 22:18:40 +0000127 // Wait for all worker threads to start
Marc Slemko3ea00332006-08-17 01:11:13 +0000128
129 {Synchronized s(_monitor);
David Reiss0c90f6f2008-02-06 22:18:40 +0000130 while(_workerCount == 0) {
131 _monitor.wait();
132 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000133 }
134
135 _startTime = Util::currentTime();
136
137 _transport->open();
138
Marc Slemkod97eb612006-08-24 23:37:36 +0000139 switch(_loopType) {
140 case T_VOID: loopEchoVoid(); break;
141 case T_BYTE: loopEchoByte(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000142 case T_I32: loopEchoI32(); break;
143 case T_I64: loopEchoI64(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000144 case T_STRING: loopEchoString(); break;
145 default: cerr << "Unexpected loop type" << _loopType << endl; break;
Marc Slemko3ea00332006-08-17 01:11:13 +0000146 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000147
Marc Slemko3ea00332006-08-17 01:11:13 +0000148 _endTime = Util::currentTime();
149
150 _transport->close();
David Reiss0c90f6f2008-02-06 22:18:40 +0000151
Marc Slemko3ea00332006-08-17 01:11:13 +0000152 _done = true;
David Reiss0c90f6f2008-02-06 22:18:40 +0000153
Marc Slemko3ea00332006-08-17 01:11:13 +0000154 {Synchronized s(_monitor);
155
156 _workerCount--;
David Reiss0c90f6f2008-02-06 22:18:40 +0000157
Mark Slee3e5d2d72007-06-15 01:45:56 +0000158 if (_workerCount == 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000159
160 _monitor.notify();
Marc Slemko3ea00332006-08-17 01:11:13 +0000161 }
162 }
163 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000164
165 void loopEchoVoid() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000166 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000167 _client->echoVoid();
168 }
169 }
170
171 void loopEchoByte() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000172 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000173 int8_t arg = 1;
174 int8_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000175 result =_client->echoByte(arg);
176 assert(result == arg);
177 }
178 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000179
Marc Slemkod97eb612006-08-24 23:37:36 +0000180 void loopEchoI32() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000181 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000182 int32_t arg = 1;
183 int32_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000184 result =_client->echoI32(arg);
185 assert(result == arg);
186 }
187 }
188
189 void loopEchoI64() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000190 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000191 int64_t arg = 1;
192 int64_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000193 result =_client->echoI64(arg);
194 assert(result == arg);
195 }
196 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000197
Marc Slemkod97eb612006-08-24 23:37:36 +0000198 void loopEchoString() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000199 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000200 string arg = "hello";
201 string result;
Mark Slee739dbe52007-02-01 22:55:30 +0000202 _client->echoString(result, arg);
Marc Slemkod97eb612006-08-24 23:37:36 +0000203 assert(result == arg);
204 }
205 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000206
Marc Slemko3ea00332006-08-17 01:11:13 +0000207 shared_ptr<TTransport> _transport;
208 shared_ptr<ServiceClient> _client;
209 Monitor& _monitor;
210 size_t& _workerCount;
211 size_t _loopCount;
Marc Slemkod97eb612006-08-24 23:37:36 +0000212 TType _loopType;
Marc Slemko3ea00332006-08-17 01:11:13 +0000213 long long _startTime;
214 long long _endTime;
215 bool _done;
216 Monitor _sleep;
217};
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000218
219
Marc Slemko3ea00332006-08-17 01:11:13 +0000220int main(int argc, char **argv) {
221
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000222 int port = 9091;
Marc Slemko3ea00332006-08-17 01:11:13 +0000223 string serverType = "thread-pool";
224 string protocolType = "binary";
225 size_t workerCount = 4;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000226 size_t clientCount = 20;
227 size_t loopCount = 50000;
Marc Slemkod97eb612006-08-24 23:37:36 +0000228 TType loopType = T_VOID;
229 string callName = "echoVoid";
Marc Slemkob09f5882006-08-23 22:03:34 +0000230 bool runServer = true;
Aditya Agarwal3950f472006-10-11 02:50:15 +0000231 bool logRequests = false;
232 string requestLogPath = "./requestlog.tlog";
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000233 bool replayRequests = false;
Marc Slemko3ea00332006-08-17 01:11:13 +0000234
Marc Slemkob09f5882006-08-23 22:03:34 +0000235 ostringstream usage;
Marc Slemko3ea00332006-08-17 01:11:13 +0000236
237 usage <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000238 argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--clients=<client-count>] [--loop=<loop-count>]" << endl <<
239 "\tclients Number of client threads to create - 0 implies no clients, i.e. server only. Default is " << clientCount << endl <<
240 "\thelp Prints this help text." << endl <<
Marc Slemkod97eb612006-08-24 23:37:36 +0000241 "\tcall Service method to call. Default is " << callName << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000242 "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl <<
243 "\tport The port the server and clients should bind to for thrift network connections. Default is " << port << endl <<
244 "\tserver Run the Thrift server in this process. Default is " << runServer << endl <<
245 "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
246 "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
Aditya Agarwal3950f472006-10-11 02:50:15 +0000247 "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000248 "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000249 "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000250
251
Marc Slemko3ea00332006-08-17 01:11:13 +0000252 map<string, string> args;
David Reiss0c90f6f2008-02-06 22:18:40 +0000253
Mark Slee3e5d2d72007-06-15 01:45:56 +0000254 for (int ix = 1; ix < argc; ix++) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000255
256 string arg(argv[ix]);
257
Mark Slee3e5d2d72007-06-15 01:45:56 +0000258 if (arg.compare(0,2, "--") == 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000259
260 size_t end = arg.find_first_of("=", 2);
261
Marc Slemko056f9ba2006-08-17 02:59:05 +0000262 string key = string(arg, 2, end - 2);
263
Mark Slee3e5d2d72007-06-15 01:45:56 +0000264 if (end != string::npos) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000265 args[key] = string(arg, end + 1);
Marc Slemko3ea00332006-08-17 01:11:13 +0000266 } else {
David Reiss0c90f6f2008-02-06 22:18:40 +0000267 args[key] = "true";
Marc Slemko3ea00332006-08-17 01:11:13 +0000268 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000269 } else {
270 throw invalid_argument("Unexcepted command line token: "+arg);
271 }
272 }
273
274 try {
275
Mark Slee3e5d2d72007-06-15 01:45:56 +0000276 if (!args["clients"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000277 clientCount = atoi(args["clients"].c_str());
278 }
279
Mark Slee3e5d2d72007-06-15 01:45:56 +0000280 if (!args["help"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000281 cerr << usage.str();
282 return 0;
283 }
284
Mark Slee3e5d2d72007-06-15 01:45:56 +0000285 if (!args["loop"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000286 loopCount = atoi(args["loop"].c_str());
287 }
288
Mark Slee3e5d2d72007-06-15 01:45:56 +0000289 if (!args["call"].empty()) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000290 callName = args["call"];
291 }
292
Mark Slee3e5d2d72007-06-15 01:45:56 +0000293 if (!args["port"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000294 port = atoi(args["port"].c_str());
295 }
296
Mark Slee3e5d2d72007-06-15 01:45:56 +0000297 if (!args["server"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000298 runServer = args["server"] == "true";
299 }
300
Mark Slee3e5d2d72007-06-15 01:45:56 +0000301 if (!args["log-request"].empty()) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000302 logRequests = args["log-request"] == "true";
303 }
304
Mark Slee3e5d2d72007-06-15 01:45:56 +0000305 if (!args["replay-request"].empty()) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000306 replayRequests = args["replay-request"] == "true";
307 }
308
Mark Slee3e5d2d72007-06-15 01:45:56 +0000309 if (!args["server-type"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000310 serverType = args["server-type"];
David Reiss0c90f6f2008-02-06 22:18:40 +0000311
Mark Slee3e5d2d72007-06-15 01:45:56 +0000312 if (serverType == "simple") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000313
Mark Slee3e5d2d72007-06-15 01:45:56 +0000314 } else if (serverType == "thread-pool") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000315
Mark Slee3e5d2d72007-06-15 01:45:56 +0000316 } else if (serverType == "threaded") {
Mark Slee739dbe52007-02-01 22:55:30 +0000317
Marc Slemko3ea00332006-08-17 01:11:13 +0000318 } else {
319
David Reiss0c90f6f2008-02-06 22:18:40 +0000320 throw invalid_argument("Unknown server type "+serverType);
Marc Slemko3ea00332006-08-17 01:11:13 +0000321 }
322 }
323
Mark Slee3e5d2d72007-06-15 01:45:56 +0000324 if (!args["workers"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000325 workerCount = atoi(args["workers"].c_str());
326 }
327
Marc Slemko3ea00332006-08-17 01:11:13 +0000328 } catch(exception& e) {
329 cerr << e.what() << endl;
330 cerr << usage;
331 }
332
Marc Slemko3ea00332006-08-17 01:11:13 +0000333 shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
334
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000335 // Dispatcher
336 shared_ptr<Server> serviceHandler(new Server());
Marc Slemko3ea00332006-08-17 01:11:13 +0000337
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000338 if (replayRequests) {
339 shared_ptr<Server> serviceHandler(new Server());
340 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
David Reiss0c90f6f2008-02-06 22:18:40 +0000341
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000342 // Transports
343 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
344 fileTransport->setChunkSize(2 * 1024 * 1024);
345 fileTransport->setMaxEventSize(1024 * 16);
346 fileTransport->seekToEnd();
347
348 // Protocol Factory
349 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
350
351 TFileProcessor fileProcessor(serviceProcessor,
352 protocolFactory,
353 fileTransport);
354
David Reiss0c90f6f2008-02-06 22:18:40 +0000355 fileProcessor.process(0, true);
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000356 exit(0);
357 }
358
359
Mark Slee3e5d2d72007-06-15 01:45:56 +0000360 if (runServer) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000361
Mark Sleed7173472006-10-25 19:52:10 +0000362 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Marc Slemko3ea00332006-08-17 01:11:13 +0000363
Marc Slemkob09f5882006-08-23 22:03:34 +0000364 // Transport
365 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Marc Slemko3ea00332006-08-17 01:11:13 +0000366
Aditya Agarwal3950f472006-10-11 02:50:15 +0000367 // Transport Factory
368 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
369
Mark Sleed7173472006-10-25 19:52:10 +0000370 // Protocol Factory
371 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000372
373 if (logRequests) {
374 // initialize the log file
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000375 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
376 fileTransport->setChunkSize(2 * 1024 * 1024);
377 fileTransport->setMaxEventSize(1024 * 16);
David Reiss0c90f6f2008-02-06 22:18:40 +0000378
379 transportFactory =
Mark Slee79e41b82007-02-07 04:07:07 +0000380 shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Aditya Agarwal3950f472006-10-11 02:50:15 +0000381 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000382
Marc Slemkob09f5882006-08-23 22:03:34 +0000383 shared_ptr<Thread> serverThread;
Marc Slemko3ea00332006-08-17 01:11:13 +0000384
Mark Slee3e5d2d72007-06-15 01:45:56 +0000385 if (serverType == "simple") {
David Reiss0c90f6f2008-02-06 22:18:40 +0000386
Mark Sleed7173472006-10-25 19:52:10 +0000387 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
David Reiss0c90f6f2008-02-06 22:18:40 +0000388
Mark Slee739dbe52007-02-01 22:55:30 +0000389 } else if (serverType == "threaded") {
390
391 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadedServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
David Reiss0c90f6f2008-02-06 22:18:40 +0000392
Mark Slee3e5d2d72007-06-15 01:45:56 +0000393 } else if (serverType == "thread-pool") {
Marc Slemkob09f5882006-08-23 22:03:34 +0000394
395 shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
396
397 threadManager->threadFactory(threadFactory);
David Reiss0c90f6f2008-02-06 22:18:40 +0000398 threadManager->start();
Mark Sleed7173472006-10-25 19:52:10 +0000399 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadPoolServer(serviceProcessor, serverSocket, transportFactory, protocolFactory, threadManager)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000400 }
401
402 cerr << "Starting the server on port " << port << endl;
403
404 serverThread->start();
David Reiss0c90f6f2008-02-06 22:18:40 +0000405
Marc Slemkob09f5882006-08-23 22:03:34 +0000406 // If we aren't running clients, just wait forever for external clients
407
Mark Sleed7173472006-10-25 19:52:10 +0000408 if (clientCount == 0) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000409 serverThread->join();
410 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000411 }
412
Mark Sleed7173472006-10-25 19:52:10 +0000413 if (clientCount > 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000414
Marc Slemkob09f5882006-08-23 22:03:34 +0000415 Monitor monitor;
Marc Slemko3ea00332006-08-17 01:11:13 +0000416
Marc Slemkob09f5882006-08-23 22:03:34 +0000417 size_t threadCount = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000418
Marc Slemkob09f5882006-08-23 22:03:34 +0000419 set<shared_ptr<Thread> > clientThreads;
Marc Slemko3ea00332006-08-17 01:11:13 +0000420
Mark Slee3e5d2d72007-06-15 01:45:56 +0000421 if (callName == "echoVoid") { loopType = T_VOID;}
422 else if (callName == "echoByte") { loopType = T_BYTE;}
423 else if (callName == "echoI32") { loopType = T_I32;}
424 else if (callName == "echoI64") { loopType = T_I64;}
425 else if (callName == "echoString") { loopType = T_STRING;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000426 else {throw invalid_argument("Unknown service call "+callName);}
427
Mark Slee3e5d2d72007-06-15 01:45:56 +0000428 for (size_t ix = 0; ix < clientCount; ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000429
Bryan Duxbury346a2682010-08-15 23:04:12 +0000430 shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
Marc Slemkob09f5882006-08-23 22:03:34 +0000431 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
Mark Slee739dbe52007-02-01 22:55:30 +0000432 shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
Mark Sleed7173472006-10-25 19:52:10 +0000433 shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
David Reiss0c90f6f2008-02-06 22:18:40 +0000434
Aditya Agarwal3950f472006-10-11 02:50:15 +0000435 clientThreads.insert(threadFactory->newThread(shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Marc Slemkob09f5882006-08-23 22:03:34 +0000436 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000437
Mark Slee3e5d2d72007-06-15 01:45:56 +0000438 for (std::set<shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000439 (*thread)->start();
440 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000441
Marc Slemkob09f5882006-08-23 22:03:34 +0000442 long long time00;
443 long long time01;
David Reiss0c90f6f2008-02-06 22:18:40 +0000444
Marc Slemkob09f5882006-08-23 22:03:34 +0000445 {Synchronized s(monitor);
446 threadCount = clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000447
Marc Slemkob09f5882006-08-23 22:03:34 +0000448 cerr << "Launch "<< clientCount << " client threads" << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000449
Marc Slemkob09f5882006-08-23 22:03:34 +0000450 time00 = Util::currentTime();
David Reiss0c90f6f2008-02-06 22:18:40 +0000451
Marc Slemkob09f5882006-08-23 22:03:34 +0000452 monitor.notifyAll();
David Reiss0c90f6f2008-02-06 22:18:40 +0000453
Marc Slemkob09f5882006-08-23 22:03:34 +0000454 while(threadCount > 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000455 monitor.wait();
Marc Slemkob09f5882006-08-23 22:03:34 +0000456 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000457
Marc Slemkob09f5882006-08-23 22:03:34 +0000458 time01 = Util::currentTime();
Marc Slemko3ea00332006-08-17 01:11:13 +0000459 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000460
Marc Slemkob09f5882006-08-23 22:03:34 +0000461 long long firstTime = 9223372036854775807LL;
462 long long lastTime = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000463
Marc Slemkob09f5882006-08-23 22:03:34 +0000464 double averageTime = 0;
465 long long minTime = 9223372036854775807LL;
466 long long maxTime = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000467
Mark Slee3e5d2d72007-06-15 01:45:56 +0000468 for (set<shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000469
Marc Slemkob09f5882006-08-23 22:03:34 +0000470 shared_ptr<ClientThread> client = dynamic_pointer_cast<ClientThread>((*ix)->runnable());
David Reiss0c90f6f2008-02-06 22:18:40 +0000471
Marc Slemkob09f5882006-08-23 22:03:34 +0000472 long long delta = client->_endTime - client->_startTime;
David Reiss0c90f6f2008-02-06 22:18:40 +0000473
Marc Slemkob09f5882006-08-23 22:03:34 +0000474 assert(delta > 0);
Marc Slemko056f9ba2006-08-17 02:59:05 +0000475
Mark Slee3e5d2d72007-06-15 01:45:56 +0000476 if (client->_startTime < firstTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000477 firstTime = client->_startTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000478 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000479
Mark Slee3e5d2d72007-06-15 01:45:56 +0000480 if (client->_endTime > lastTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000481 lastTime = client->_endTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000482 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000483
Mark Slee3e5d2d72007-06-15 01:45:56 +0000484 if (delta < minTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000485 minTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000486 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000487
Mark Slee3e5d2d72007-06-15 01:45:56 +0000488 if (delta > maxTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000489 maxTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000490 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000491
Marc Slemkob09f5882006-08-23 22:03:34 +0000492 averageTime+= delta;
493 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000494
Marc Slemkob09f5882006-08-23 22:03:34 +0000495 averageTime /= clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000496
497
Marc Slemkob09f5882006-08-23 22:03:34 +0000498 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000499
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000500 count_map count = serviceHandler->getCount();
501 count_map::iterator iter;
502 for (iter = count.begin(); iter != count.end(); ++iter) {
503 printf("%s => %d\n", iter->first, iter->second);
504 }
Marc Slemkob09f5882006-08-23 22:03:34 +0000505 cerr << "done." << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000506 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000507
Marc Slemko3ea00332006-08-17 01:11:13 +0000508 return 0;
509}