blob: 78491d621bcec31ae79e8dcaed9789fd50c48ff2 [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;
Mark Sleef4f18ec2007-05-16 21:22:34 +000029using namespace boost;
Marc Slemko3ea00332006-08-17 01:11:13 +000030
31using namespace facebook::thrift;
32using namespace facebook::thrift::protocol;
33using namespace facebook::thrift::transport;
34using namespace facebook::thrift::server;
Mark Sleeb9ff32a2006-11-16 01:00:24 +000035using namespace facebook::thrift::concurrency;
Marc Slemko3ea00332006-08-17 01:11:13 +000036
37using namespace test::stress;
38
Mark Sleeb9ff32a2006-11-16 01:00:24 +000039struct eqstr {
40 bool operator()(const char* s1, const char* s2) const {
41 return strcmp(s1, s2) == 0;
42 }
43};
44
45struct ltstr {
46 bool operator()(const char* s1, const char* s2) const {
47 return strcmp(s1, s2) < 0;
48 }
49};
50
51
David Reiss0c90f6f2008-02-06 22:18:40 +000052// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
53typedef map<const char*, int, ltstr> count_map;
Mark Sleeb9ff32a2006-11-16 01:00:24 +000054
Aditya Agarwal3950f472006-10-11 02:50:15 +000055class Server : public ServiceIf {
Marc Slemko3ea00332006-08-17 01:11:13 +000056 public:
Mark Sleeb9ff32a2006-11-16 01:00:24 +000057 Server() {}
58
59 void count(const char* method) {
David Reiss46379902008-02-04 19:23:57 +000060 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000061 int ct = counts_[method];
62 counts_[method] = ++ct;
63 }
64
65 void echoVoid() {
66 count("echoVoid");
67 return;
68 }
69
70 count_map getCount() {
David Reiss46379902008-02-04 19:23:57 +000071 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000072 return counts_;
73 }
74
Mark Slee739dbe52007-02-01 22:55:30 +000075 int8_t echoByte(const int8_t arg) {return arg;}
76 int32_t echoI32(const int32_t arg) {return arg;}
77 int64_t echoI64(const int64_t arg) {return arg;}
78 void echoString(string& out, const string &arg) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000079 if (arg != "hello") {
80 T_ERROR_ABORT("WRONG STRING!!!!");
81 }
Mark Slee739dbe52007-02-01 22:55:30 +000082 out = arg;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000083 }
Mark Slee739dbe52007-02-01 22:55:30 +000084 void echoList(vector<int8_t> &out, const vector<int8_t> &arg) { out = arg; }
85 void echoSet(set<int8_t> &out, const set<int8_t> &arg) { out = arg; }
86 void echoMap(map<int8_t, int8_t> &out, const map<int8_t, int8_t> &arg) { out = arg; }
Mark Sleeb9ff32a2006-11-16 01:00:24 +000087
88private:
89 count_map counts_;
90 Mutex lock_;
91
Marc Slemko3ea00332006-08-17 01:11:13 +000092};
93
94class ClientThread: public Runnable {
95public:
96
Marc Slemkod97eb612006-08-24 23:37:36 +000097 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 +000098 _transport(transport),
99 _client(client),
100 _monitor(monitor),
101 _workerCount(workerCount),
Marc Slemkod97eb612006-08-24 23:37:36 +0000102 _loopCount(loopCount),
103 _loopType(loopType)
Marc Slemko3ea00332006-08-17 01:11:13 +0000104 {}
105
106 void run() {
107
David Reiss0c90f6f2008-02-06 22:18:40 +0000108 // Wait for all worker threads to start
Marc Slemko3ea00332006-08-17 01:11:13 +0000109
110 {Synchronized s(_monitor);
David Reiss0c90f6f2008-02-06 22:18:40 +0000111 while(_workerCount == 0) {
112 _monitor.wait();
113 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000114 }
115
116 _startTime = Util::currentTime();
117
118 _transport->open();
119
Marc Slemkod97eb612006-08-24 23:37:36 +0000120 switch(_loopType) {
121 case T_VOID: loopEchoVoid(); break;
122 case T_BYTE: loopEchoByte(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000123 case T_I32: loopEchoI32(); break;
124 case T_I64: loopEchoI64(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000125 case T_STRING: loopEchoString(); break;
126 default: cerr << "Unexpected loop type" << _loopType << endl; break;
Marc Slemko3ea00332006-08-17 01:11:13 +0000127 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000128
Marc Slemko3ea00332006-08-17 01:11:13 +0000129 _endTime = Util::currentTime();
130
131 _transport->close();
David Reiss0c90f6f2008-02-06 22:18:40 +0000132
Marc Slemko3ea00332006-08-17 01:11:13 +0000133 _done = true;
David Reiss0c90f6f2008-02-06 22:18:40 +0000134
Marc Slemko3ea00332006-08-17 01:11:13 +0000135 {Synchronized s(_monitor);
136
137 _workerCount--;
David Reiss0c90f6f2008-02-06 22:18:40 +0000138
Mark Slee3e5d2d72007-06-15 01:45:56 +0000139 if (_workerCount == 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000140
141 _monitor.notify();
Marc Slemko3ea00332006-08-17 01:11:13 +0000142 }
143 }
144 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000145
146 void loopEchoVoid() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000147 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000148 _client->echoVoid();
149 }
150 }
151
152 void loopEchoByte() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000153 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000154 int8_t arg = 1;
155 int8_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000156 result =_client->echoByte(arg);
157 assert(result == arg);
158 }
159 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000160
Marc Slemkod97eb612006-08-24 23:37:36 +0000161 void loopEchoI32() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000162 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000163 int32_t arg = 1;
164 int32_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000165 result =_client->echoI32(arg);
166 assert(result == arg);
167 }
168 }
169
170 void loopEchoI64() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000171 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000172 int64_t arg = 1;
173 int64_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000174 result =_client->echoI64(arg);
175 assert(result == arg);
176 }
177 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000178
Marc Slemkod97eb612006-08-24 23:37:36 +0000179 void loopEchoString() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000180 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000181 string arg = "hello";
182 string result;
Mark Slee739dbe52007-02-01 22:55:30 +0000183 _client->echoString(result, arg);
Marc Slemkod97eb612006-08-24 23:37:36 +0000184 assert(result == arg);
185 }
186 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000187
Marc Slemko3ea00332006-08-17 01:11:13 +0000188 shared_ptr<TTransport> _transport;
189 shared_ptr<ServiceClient> _client;
190 Monitor& _monitor;
191 size_t& _workerCount;
192 size_t _loopCount;
Marc Slemkod97eb612006-08-24 23:37:36 +0000193 TType _loopType;
Marc Slemko3ea00332006-08-17 01:11:13 +0000194 long long _startTime;
195 long long _endTime;
196 bool _done;
197 Monitor _sleep;
198};
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000199
200
Marc Slemko3ea00332006-08-17 01:11:13 +0000201int main(int argc, char **argv) {
202
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000203 int port = 9091;
Marc Slemko3ea00332006-08-17 01:11:13 +0000204 string serverType = "thread-pool";
205 string protocolType = "binary";
206 size_t workerCount = 4;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000207 size_t clientCount = 20;
208 size_t loopCount = 50000;
Marc Slemkod97eb612006-08-24 23:37:36 +0000209 TType loopType = T_VOID;
210 string callName = "echoVoid";
Marc Slemkob09f5882006-08-23 22:03:34 +0000211 bool runServer = true;
Aditya Agarwal3950f472006-10-11 02:50:15 +0000212 bool logRequests = false;
213 string requestLogPath = "./requestlog.tlog";
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000214 bool replayRequests = false;
Marc Slemko3ea00332006-08-17 01:11:13 +0000215
Marc Slemkob09f5882006-08-23 22:03:34 +0000216 ostringstream usage;
Marc Slemko3ea00332006-08-17 01:11:13 +0000217
218 usage <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000219 argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--clients=<client-count>] [--loop=<loop-count>]" << endl <<
220 "\tclients Number of client threads to create - 0 implies no clients, i.e. server only. Default is " << clientCount << endl <<
221 "\thelp Prints this help text." << endl <<
Marc Slemkod97eb612006-08-24 23:37:36 +0000222 "\tcall Service method to call. Default is " << callName << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000223 "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl <<
224 "\tport The port the server and clients should bind to for thrift network connections. Default is " << port << endl <<
225 "\tserver Run the Thrift server in this process. Default is " << runServer << endl <<
226 "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
227 "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
Aditya Agarwal3950f472006-10-11 02:50:15 +0000228 "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000229 "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000230 "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000231
232
Marc Slemko3ea00332006-08-17 01:11:13 +0000233 map<string, string> args;
David Reiss0c90f6f2008-02-06 22:18:40 +0000234
Mark Slee3e5d2d72007-06-15 01:45:56 +0000235 for (int ix = 1; ix < argc; ix++) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000236
237 string arg(argv[ix]);
238
Mark Slee3e5d2d72007-06-15 01:45:56 +0000239 if (arg.compare(0,2, "--") == 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000240
241 size_t end = arg.find_first_of("=", 2);
242
Marc Slemko056f9ba2006-08-17 02:59:05 +0000243 string key = string(arg, 2, end - 2);
244
Mark Slee3e5d2d72007-06-15 01:45:56 +0000245 if (end != string::npos) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000246 args[key] = string(arg, end + 1);
Marc Slemko3ea00332006-08-17 01:11:13 +0000247 } else {
David Reiss0c90f6f2008-02-06 22:18:40 +0000248 args[key] = "true";
Marc Slemko3ea00332006-08-17 01:11:13 +0000249 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000250 } else {
251 throw invalid_argument("Unexcepted command line token: "+arg);
252 }
253 }
254
255 try {
256
Mark Slee3e5d2d72007-06-15 01:45:56 +0000257 if (!args["clients"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000258 clientCount = atoi(args["clients"].c_str());
259 }
260
Mark Slee3e5d2d72007-06-15 01:45:56 +0000261 if (!args["help"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000262 cerr << usage.str();
263 return 0;
264 }
265
Mark Slee3e5d2d72007-06-15 01:45:56 +0000266 if (!args["loop"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000267 loopCount = atoi(args["loop"].c_str());
268 }
269
Mark Slee3e5d2d72007-06-15 01:45:56 +0000270 if (!args["call"].empty()) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000271 callName = args["call"];
272 }
273
Mark Slee3e5d2d72007-06-15 01:45:56 +0000274 if (!args["port"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000275 port = atoi(args["port"].c_str());
276 }
277
Mark Slee3e5d2d72007-06-15 01:45:56 +0000278 if (!args["server"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000279 runServer = args["server"] == "true";
280 }
281
Mark Slee3e5d2d72007-06-15 01:45:56 +0000282 if (!args["log-request"].empty()) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000283 logRequests = args["log-request"] == "true";
284 }
285
Mark Slee3e5d2d72007-06-15 01:45:56 +0000286 if (!args["replay-request"].empty()) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000287 replayRequests = args["replay-request"] == "true";
288 }
289
Mark Slee3e5d2d72007-06-15 01:45:56 +0000290 if (!args["server-type"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000291 serverType = args["server-type"];
David Reiss0c90f6f2008-02-06 22:18:40 +0000292
Mark Slee3e5d2d72007-06-15 01:45:56 +0000293 if (serverType == "simple") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000294
Mark Slee3e5d2d72007-06-15 01:45:56 +0000295 } else if (serverType == "thread-pool") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000296
Mark Slee3e5d2d72007-06-15 01:45:56 +0000297 } else if (serverType == "threaded") {
Mark Slee739dbe52007-02-01 22:55:30 +0000298
Marc Slemko3ea00332006-08-17 01:11:13 +0000299 } else {
300
David Reiss0c90f6f2008-02-06 22:18:40 +0000301 throw invalid_argument("Unknown server type "+serverType);
Marc Slemko3ea00332006-08-17 01:11:13 +0000302 }
303 }
304
Mark Slee3e5d2d72007-06-15 01:45:56 +0000305 if (!args["workers"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000306 workerCount = atoi(args["workers"].c_str());
307 }
308
Marc Slemko3ea00332006-08-17 01:11:13 +0000309 } catch(exception& e) {
310 cerr << e.what() << endl;
311 cerr << usage;
312 }
313
Marc Slemko3ea00332006-08-17 01:11:13 +0000314 shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
315
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000316 // Dispatcher
317 shared_ptr<Server> serviceHandler(new Server());
Marc Slemko3ea00332006-08-17 01:11:13 +0000318
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000319 if (replayRequests) {
320 shared_ptr<Server> serviceHandler(new Server());
321 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
David Reiss0c90f6f2008-02-06 22:18:40 +0000322
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000323 // Transports
324 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
325 fileTransport->setChunkSize(2 * 1024 * 1024);
326 fileTransport->setMaxEventSize(1024 * 16);
327 fileTransport->seekToEnd();
328
329 // Protocol Factory
330 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
331
332 TFileProcessor fileProcessor(serviceProcessor,
333 protocolFactory,
334 fileTransport);
335
David Reiss0c90f6f2008-02-06 22:18:40 +0000336 fileProcessor.process(0, true);
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000337 exit(0);
338 }
339
340
Mark Slee3e5d2d72007-06-15 01:45:56 +0000341 if (runServer) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000342
Mark Sleed7173472006-10-25 19:52:10 +0000343 shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Marc Slemko3ea00332006-08-17 01:11:13 +0000344
Marc Slemkob09f5882006-08-23 22:03:34 +0000345 // Transport
346 shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Marc Slemko3ea00332006-08-17 01:11:13 +0000347
Aditya Agarwal3950f472006-10-11 02:50:15 +0000348 // Transport Factory
349 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
350
Mark Sleed7173472006-10-25 19:52:10 +0000351 // Protocol Factory
352 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000353
354 if (logRequests) {
355 // initialize the log file
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000356 shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
357 fileTransport->setChunkSize(2 * 1024 * 1024);
358 fileTransport->setMaxEventSize(1024 * 16);
David Reiss0c90f6f2008-02-06 22:18:40 +0000359
360 transportFactory =
Mark Slee79e41b82007-02-07 04:07:07 +0000361 shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Aditya Agarwal3950f472006-10-11 02:50:15 +0000362 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000363
Marc Slemkob09f5882006-08-23 22:03:34 +0000364 shared_ptr<Thread> serverThread;
Marc Slemko3ea00332006-08-17 01:11:13 +0000365
Mark Slee3e5d2d72007-06-15 01:45:56 +0000366 if (serverType == "simple") {
David Reiss0c90f6f2008-02-06 22:18:40 +0000367
Mark Sleed7173472006-10-25 19:52:10 +0000368 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
David Reiss0c90f6f2008-02-06 22:18:40 +0000369
Mark Slee739dbe52007-02-01 22:55:30 +0000370 } else if (serverType == "threaded") {
371
372 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadedServer(serviceProcessor, serverSocket, transportFactory, protocolFactory)));
David Reiss0c90f6f2008-02-06 22:18:40 +0000373
Mark Slee3e5d2d72007-06-15 01:45:56 +0000374 } else if (serverType == "thread-pool") {
Marc Slemkob09f5882006-08-23 22:03:34 +0000375
376 shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
377
378 threadManager->threadFactory(threadFactory);
David Reiss0c90f6f2008-02-06 22:18:40 +0000379 threadManager->start();
Mark Sleed7173472006-10-25 19:52:10 +0000380 serverThread = threadFactory->newThread(shared_ptr<TServer>(new TThreadPoolServer(serviceProcessor, serverSocket, transportFactory, protocolFactory, threadManager)));
Marc Slemkob09f5882006-08-23 22:03:34 +0000381 }
382
383 cerr << "Starting the server on port " << port << endl;
384
385 serverThread->start();
David Reiss0c90f6f2008-02-06 22:18:40 +0000386
Marc Slemkob09f5882006-08-23 22:03:34 +0000387 // If we aren't running clients, just wait forever for external clients
388
Mark Sleed7173472006-10-25 19:52:10 +0000389 if (clientCount == 0) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000390 serverThread->join();
391 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000392 }
393
Mark Sleed7173472006-10-25 19:52:10 +0000394 if (clientCount > 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000395
Marc Slemkob09f5882006-08-23 22:03:34 +0000396 Monitor monitor;
Marc Slemko3ea00332006-08-17 01:11:13 +0000397
Marc Slemkob09f5882006-08-23 22:03:34 +0000398 size_t threadCount = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000399
Marc Slemkob09f5882006-08-23 22:03:34 +0000400 set<shared_ptr<Thread> > clientThreads;
Marc Slemko3ea00332006-08-17 01:11:13 +0000401
Mark Slee3e5d2d72007-06-15 01:45:56 +0000402 if (callName == "echoVoid") { loopType = T_VOID;}
403 else if (callName == "echoByte") { loopType = T_BYTE;}
404 else if (callName == "echoI32") { loopType = T_I32;}
405 else if (callName == "echoI64") { loopType = T_I64;}
406 else if (callName == "echoString") { loopType = T_STRING;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000407 else {throw invalid_argument("Unknown service call "+callName);}
408
Mark Slee3e5d2d72007-06-15 01:45:56 +0000409 for (size_t ix = 0; ix < clientCount; ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000410
Marc Slemkob09f5882006-08-23 22:03:34 +0000411 shared_ptr<TSocket> socket(new TSocket("127.0.01", port));
412 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
Mark Slee739dbe52007-02-01 22:55:30 +0000413 shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
Mark Sleed7173472006-10-25 19:52:10 +0000414 shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
David Reiss0c90f6f2008-02-06 22:18:40 +0000415
Aditya Agarwal3950f472006-10-11 02:50:15 +0000416 clientThreads.insert(threadFactory->newThread(shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Marc Slemkob09f5882006-08-23 22:03:34 +0000417 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000418
Mark Slee3e5d2d72007-06-15 01:45:56 +0000419 for (std::set<shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000420 (*thread)->start();
421 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000422
Marc Slemkob09f5882006-08-23 22:03:34 +0000423 long long time00;
424 long long time01;
David Reiss0c90f6f2008-02-06 22:18:40 +0000425
Marc Slemkob09f5882006-08-23 22:03:34 +0000426 {Synchronized s(monitor);
427 threadCount = clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000428
Marc Slemkob09f5882006-08-23 22:03:34 +0000429 cerr << "Launch "<< clientCount << " client threads" << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000430
Marc Slemkob09f5882006-08-23 22:03:34 +0000431 time00 = Util::currentTime();
David Reiss0c90f6f2008-02-06 22:18:40 +0000432
Marc Slemkob09f5882006-08-23 22:03:34 +0000433 monitor.notifyAll();
David Reiss0c90f6f2008-02-06 22:18:40 +0000434
Marc Slemkob09f5882006-08-23 22:03:34 +0000435 while(threadCount > 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000436 monitor.wait();
Marc Slemkob09f5882006-08-23 22:03:34 +0000437 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000438
Marc Slemkob09f5882006-08-23 22:03:34 +0000439 time01 = Util::currentTime();
Marc Slemko3ea00332006-08-17 01:11:13 +0000440 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000441
Marc Slemkob09f5882006-08-23 22:03:34 +0000442 long long firstTime = 9223372036854775807LL;
443 long long lastTime = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000444
Marc Slemkob09f5882006-08-23 22:03:34 +0000445 double averageTime = 0;
446 long long minTime = 9223372036854775807LL;
447 long long maxTime = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000448
Mark Slee3e5d2d72007-06-15 01:45:56 +0000449 for (set<shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000450
Marc Slemkob09f5882006-08-23 22:03:34 +0000451 shared_ptr<ClientThread> client = dynamic_pointer_cast<ClientThread>((*ix)->runnable());
David Reiss0c90f6f2008-02-06 22:18:40 +0000452
Marc Slemkob09f5882006-08-23 22:03:34 +0000453 long long delta = client->_endTime - client->_startTime;
David Reiss0c90f6f2008-02-06 22:18:40 +0000454
Marc Slemkob09f5882006-08-23 22:03:34 +0000455 assert(delta > 0);
Marc Slemko056f9ba2006-08-17 02:59:05 +0000456
Mark Slee3e5d2d72007-06-15 01:45:56 +0000457 if (client->_startTime < firstTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000458 firstTime = client->_startTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000459 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000460
Mark Slee3e5d2d72007-06-15 01:45:56 +0000461 if (client->_endTime > lastTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000462 lastTime = client->_endTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000463 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000464
Mark Slee3e5d2d72007-06-15 01:45:56 +0000465 if (delta < minTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000466 minTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000467 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000468
Mark Slee3e5d2d72007-06-15 01:45:56 +0000469 if (delta > maxTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000470 maxTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000471 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000472
Marc Slemkob09f5882006-08-23 22:03:34 +0000473 averageTime+= delta;
474 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000475
Marc Slemkob09f5882006-08-23 22:03:34 +0000476 averageTime /= clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000477
478
Marc Slemkob09f5882006-08-23 22:03:34 +0000479 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000480
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000481 count_map count = serviceHandler->getCount();
482 count_map::iterator iter;
483 for (iter = count.begin(); iter != count.end(); ++iter) {
484 printf("%s => %d\n", iter->first, iter->second);
485 }
Marc Slemkob09f5882006-08-23 22:03:34 +0000486 cerr << "done." << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000487 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000488
Marc Slemko3ea00332006-08-17 01:11:13 +0000489 return 0;
490}