blob: 20320c7d033f574fab29ac826a8f43b76e294bd3 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meier49ff8b12012-04-13 09:12:31 +000020#include <thrift/concurrency/ThreadManager.h>
21#include <thrift/concurrency/PlatformThreadFactory.h>
22#include <thrift/concurrency/Monitor.h>
23#include <thrift/concurrency/Util.h>
24#include <thrift/concurrency/Mutex.h>
25#include <thrift/protocol/TBinaryProtocol.h>
26#include <thrift/server/TSimpleServer.h>
27#include <thrift/server/TThreadPoolServer.h>
28#include <thrift/server/TThreadedServer.h>
29#include <thrift/server/TNonblockingServer.h>
30#include <thrift/transport/TServerSocket.h>
31#include <thrift/transport/TSocket.h>
32#include <thrift/transport/TTransportUtils.h>
33#include <thrift/transport/TFileTransport.h>
Roger Meier33eaa0f2012-04-13 09:13:13 +000034#include <thrift/TLogging.h>
Mark Sleee02385b2007-06-09 01:21:16 +000035
36#include "Service.h"
37
38#include <boost/shared_ptr.hpp>
39
40#include <iostream>
41#include <set>
42#include <stdexcept>
43#include <sstream>
Mark Sleee02385b2007-06-09 01:21:16 +000044#include <map>
Jake Farrell5d02b802014-01-07 21:42:01 -050045#if _WIN32
Konrad Grochowski240120c2014-11-18 11:33:31 +010046 #include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050047#endif
Mark Sleee02385b2007-06-09 01:21:16 +000048
49using namespace std;
Mark Sleee02385b2007-06-09 01:21:16 +000050
T Jake Lucianib5e62212009-01-31 22:36:20 +000051using namespace apache::thrift;
52using namespace apache::thrift::protocol;
53using namespace apache::thrift::transport;
54using namespace apache::thrift::server;
55using namespace apache::thrift::concurrency;
Mark Sleee02385b2007-06-09 01:21:16 +000056
57using namespace test::stress;
58
59struct eqstr {
Konrad Grochowski240120c2014-11-18 11:33:31 +010060 bool operator()(const char* s1, const char* s2) const {
61 return strcmp(s1, s2) == 0;
62 }
Mark Sleee02385b2007-06-09 01:21:16 +000063};
64
65struct ltstr {
Konrad Grochowski240120c2014-11-18 11:33:31 +010066 bool operator()(const char* s1, const char* s2) const {
67 return strcmp(s1, s2) < 0;
68 }
Mark Sleee02385b2007-06-09 01:21:16 +000069};
70
Konrad Grochowski240120c2014-11-18 11:33:31 +010071
Mark Sleee02385b2007-06-09 01:21:16 +000072// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
73typedef map<const char*, int, ltstr> count_map;
74
75class Server : public ServiceIf {
Konrad Grochowski240120c2014-11-18 11:33:31 +010076 public:
Mark Sleee02385b2007-06-09 01:21:16 +000077 Server() {}
78
79 void count(const char* method) {
Mark Slee79b16942007-11-26 19:05:29 +000080 Guard m(lock_);
Mark Sleee02385b2007-06-09 01:21:16 +000081 int ct = counts_[method];
82 counts_[method] = ++ct;
83 }
84
85 void echoVoid() {
86 count("echoVoid");
Mark Slee3e5d2d72007-06-15 01:45:56 +000087 // Sleep to simulate work
Jake Farrell5d02b802014-01-07 21:42:01 -050088 THRIFT_SLEEP_USEC(1);
Mark Sleee02385b2007-06-09 01:21:16 +000089 return;
90 }
91
92 count_map getCount() {
Mark Slee79b16942007-11-26 19:05:29 +000093 Guard m(lock_);
Mark Sleee02385b2007-06-09 01:21:16 +000094 return counts_;
95 }
96
Konrad Grochowski240120c2014-11-18 11:33:31 +010097 int8_t echoByte(const int8_t arg) {return arg;}
98 int32_t echoI32(const int32_t arg) {return arg;}
99 int64_t echoI64(const int64_t arg) {return arg;}
100 void echoString(string& out, const string &arg) {
Mark Sleee02385b2007-06-09 01:21:16 +0000101 if (arg != "hello") {
Roger Meiera8cef6e2011-07-17 18:55:59 +0000102 T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
Mark Sleee02385b2007-06-09 01:21:16 +0000103 }
104 out = arg;
105 }
Konrad Grochowski240120c2014-11-18 11:33:31 +0100106 void echoList(vector<int8_t> &out, const vector<int8_t> &arg) { out = arg; }
107 void echoSet(set<int8_t> &out, const set<int8_t> &arg) { out = arg; }
108 void echoMap(map<int8_t, int8_t> &out, const map<int8_t, int8_t> &arg) { out = arg; }
Mark Sleee02385b2007-06-09 01:21:16 +0000109
110private:
111 count_map counts_;
112 Mutex lock_;
Konrad Grochowski240120c2014-11-18 11:33:31 +0100113
Mark Sleee02385b2007-06-09 01:21:16 +0000114};
115
Konrad Grochowski240120c2014-11-18 11:33:31 +0100116class ClientThread: public Runnable {
Mark Sleee02385b2007-06-09 01:21:16 +0000117public:
Konrad Grochowski240120c2014-11-18 11:33:31 +0100118
119 ClientThread(boost::shared_ptr<TTransport>transport, boost::shared_ptr<ServiceClient> client, Monitor& monitor, size_t& workerCount, size_t loopCount, TType loopType) :
120 _transport(transport),
121 _client(client),
122 _monitor(monitor),
123 _workerCount(workerCount),
124 _loopCount(loopCount),
125 _loopType(loopType)
126 {}
Mark Sleee02385b2007-06-09 01:21:16 +0000127
128 void run() {
129
130 // Wait for all worker threads to start
131
Konrad Grochowski240120c2014-11-18 11:33:31 +0100132 {Synchronized s(_monitor);
133 while(_workerCount == 0) {
134 _monitor.wait();
135 }
Mark Sleee02385b2007-06-09 01:21:16 +0000136 }
137
138 _startTime = Util::currentTime();
139
140 _transport->open();
141
Konrad Grochowski240120c2014-11-18 11:33:31 +0100142 switch(_loopType) {
143 case T_VOID: loopEchoVoid(); break;
144 case T_BYTE: loopEchoByte(); break;
145 case T_I32: loopEchoI32(); break;
146 case T_I64: loopEchoI64(); break;
147 case T_STRING: loopEchoString(); break;
148 default: cerr << "Unexpected loop type" << _loopType << endl; break;
Mark Sleee02385b2007-06-09 01:21:16 +0000149 }
150
151 _endTime = Util::currentTime();
152
153 _transport->close();
154
155 _done = true;
156
Konrad Grochowski240120c2014-11-18 11:33:31 +0100157 {Synchronized s(_monitor);
Mark Sleee02385b2007-06-09 01:21:16 +0000158
159 _workerCount--;
160
Mark Slee3e5d2d72007-06-15 01:45:56 +0000161 if (_workerCount == 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000162
163 _monitor.notify();
164 }
165 }
166 }
167
168 void loopEchoVoid() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000169 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000170 _client->echoVoid();
171 }
172 }
173
174 void loopEchoByte() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000175 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000176 int8_t arg = 1;
177 int8_t result;
Konrad Grochowski240120c2014-11-18 11:33:31 +0100178 result =_client->echoByte(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500179 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000180 assert(result == arg);
181 }
182 }
183
184 void loopEchoI32() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000185 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000186 int32_t arg = 1;
187 int32_t result;
Konrad Grochowski240120c2014-11-18 11:33:31 +0100188 result =_client->echoI32(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500189 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000190 assert(result == arg);
191 }
192 }
193
194 void loopEchoI64() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000195 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000196 int64_t arg = 1;
197 int64_t result;
Konrad Grochowski240120c2014-11-18 11:33:31 +0100198 result =_client->echoI64(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500199 (void)result;
Mark Sleee02385b2007-06-09 01:21:16 +0000200 assert(result == arg);
201 }
202 }
203
204 void loopEchoString() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000205 for (size_t ix = 0; ix < _loopCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000206 string arg = "hello";
207 string result;
208 _client->echoString(result, arg);
209 assert(result == arg);
210 }
211 }
212
Roger Meier611f90c2011-12-11 22:08:51 +0000213 boost::shared_ptr<TTransport> _transport;
214 boost::shared_ptr<ServiceClient> _client;
Mark Sleee02385b2007-06-09 01:21:16 +0000215 Monitor& _monitor;
216 size_t& _workerCount;
217 size_t _loopCount;
218 TType _loopType;
Roger Meier5f9614c2010-11-21 16:59:05 +0000219 int64_t _startTime;
220 int64_t _endTime;
Mark Sleee02385b2007-06-09 01:21:16 +0000221 bool _done;
222 Monitor _sleep;
223};
224
Konrad Grochowski240120c2014-11-18 11:33:31 +0100225
226int main(int argc, char **argv) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500227#if _WIN32
228 transport::TWinsockSingleton::create();
229#endif
Mark Sleee02385b2007-06-09 01:21:16 +0000230
231 int port = 9091;
232 string serverType = "simple";
233 string protocolType = "binary";
Jake Farrell5d02b802014-01-07 21:42:01 -0500234 uint32_t workerCount = 4;
235 uint32_t clientCount = 20;
236 uint32_t loopCount = 1000;
Konrad Grochowski240120c2014-11-18 11:33:31 +0100237 TType loopType = T_VOID;
Mark Sleee02385b2007-06-09 01:21:16 +0000238 string callName = "echoVoid";
239 bool runServer = true;
240 bool logRequests = false;
241 string requestLogPath = "./requestlog.tlog";
242 bool replayRequests = false;
243
244 ostringstream usage;
245
Konrad Grochowski240120c2014-11-18 11:33:31 +0100246 usage <<
247 argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--clients=<client-count>] [--loop=<loop-count>]" << endl <<
248 "\tclients Number of client threads to create - 0 implies no clients, i.e. server only. Default is " << clientCount << endl <<
249 "\thelp Prints this help text." << endl <<
250 "\tcall Service method to call. Default is " << callName << endl <<
251 "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl <<
252 "\tport The port the server and clients should bind to for thrift network connections. Default is " << port << endl <<
253 "\tserver Run the Thrift server in this process. Default is " << runServer << endl <<
254 "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
255 "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
256 "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
257 "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
258 "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000259
Konrad Grochowski240120c2014-11-18 11:33:31 +0100260
261 map<string, string> args;
Mark Sleee02385b2007-06-09 01:21:16 +0000262
Mark Slee3e5d2d72007-06-15 01:45:56 +0000263 for (int ix = 1; ix < argc; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000264
265 string arg(argv[ix]);
266
Konrad Grochowski240120c2014-11-18 11:33:31 +0100267 if (arg.compare(0,2, "--") == 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000268
269 size_t end = arg.find_first_of("=", 2);
270
271 string key = string(arg, 2, end - 2);
272
Mark Slee3e5d2d72007-06-15 01:45:56 +0000273 if (end != string::npos) {
Mark Sleee02385b2007-06-09 01:21:16 +0000274 args[key] = string(arg, end + 1);
275 } else {
276 args[key] = "true";
277 }
278 } else {
Konrad Grochowski240120c2014-11-18 11:33:31 +0100279 throw invalid_argument("Unexcepted command line token: "+arg);
Mark Sleee02385b2007-06-09 01:21:16 +0000280 }
281 }
282
283 try {
284
Mark Slee3e5d2d72007-06-15 01:45:56 +0000285 if (!args["clients"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000286 clientCount = atoi(args["clients"].c_str());
287 }
288
Mark Slee3e5d2d72007-06-15 01:45:56 +0000289 if (!args["help"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000290 cerr << usage.str();
291 return 0;
292 }
293
Mark Slee3e5d2d72007-06-15 01:45:56 +0000294 if (!args["loop"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000295 loopCount = atoi(args["loop"].c_str());
296 }
297
Mark Slee3e5d2d72007-06-15 01:45:56 +0000298 if (!args["call"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000299 callName = args["call"];
300 }
301
Mark Slee3e5d2d72007-06-15 01:45:56 +0000302 if (!args["port"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000303 port = atoi(args["port"].c_str());
304 }
305
Mark Slee3e5d2d72007-06-15 01:45:56 +0000306 if (!args["server"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000307 runServer = args["server"] == "true";
308 }
309
Mark Slee3e5d2d72007-06-15 01:45:56 +0000310 if (!args["log-request"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000311 logRequests = args["log-request"] == "true";
312 }
313
Mark Slee3e5d2d72007-06-15 01:45:56 +0000314 if (!args["replay-request"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000315 replayRequests = args["replay-request"] == "true";
316 }
317
Mark Slee3e5d2d72007-06-15 01:45:56 +0000318 if (!args["server-type"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000319 serverType = args["server-type"];
320 }
321
Mark Slee3e5d2d72007-06-15 01:45:56 +0000322 if (!args["workers"].empty()) {
Mark Sleee02385b2007-06-09 01:21:16 +0000323 workerCount = atoi(args["workers"].c_str());
324 }
325
Konrad Grochowski240120c2014-11-18 11:33:31 +0100326 } catch(std::exception& e) {
Mark Sleee02385b2007-06-09 01:21:16 +0000327 cerr << e.what() << endl;
Jake Farrell5d02b802014-01-07 21:42:01 -0500328 cerr << usage.str();
Mark Sleee02385b2007-06-09 01:21:16 +0000329 }
330
Konrad Grochowski240120c2014-11-18 11:33:31 +0100331 boost::shared_ptr<PlatformThreadFactory> threadFactory = boost::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000332
333 // Dispatcher
Roger Meier611f90c2011-12-11 22:08:51 +0000334 boost::shared_ptr<Server> serviceHandler(new Server());
Mark Sleee02385b2007-06-09 01:21:16 +0000335
336 if (replayRequests) {
Roger Meier611f90c2011-12-11 22:08:51 +0000337 boost::shared_ptr<Server> serviceHandler(new Server());
338 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Mark Sleee02385b2007-06-09 01:21:16 +0000339
340 // Transports
Roger Meier611f90c2011-12-11 22:08:51 +0000341 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Mark Sleee02385b2007-06-09 01:21:16 +0000342 fileTransport->setChunkSize(2 * 1024 * 1024);
343 fileTransport->setMaxEventSize(1024 * 16);
344 fileTransport->seekToEnd();
345
346 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000347 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000348
Konrad Grochowski240120c2014-11-18 11:33:31 +0100349 TFileProcessor fileProcessor(serviceProcessor,
350 protocolFactory,
351 fileTransport);
Mark Sleee02385b2007-06-09 01:21:16 +0000352
353 fileProcessor.process(0, true);
354 exit(0);
355 }
356
Konrad Grochowski240120c2014-11-18 11:33:31 +0100357
Mark Slee3e5d2d72007-06-15 01:45:56 +0000358 if (runServer) {
Mark Sleee02385b2007-06-09 01:21:16 +0000359
Roger Meier611f90c2011-12-11 22:08:51 +0000360 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Mark Sleee02385b2007-06-09 01:21:16 +0000361
362 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000363 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Mark Sleee02385b2007-06-09 01:21:16 +0000364
365 // Transport Factory
Konrad Grochowski240120c2014-11-18 11:33:31 +0100366 boost::shared_ptr<TTransportFactory> transportFactory;
Mark Sleee02385b2007-06-09 01:21:16 +0000367
368 if (logRequests) {
369 // initialize the log file
Roger Meier611f90c2011-12-11 22:08:51 +0000370 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Mark Sleee02385b2007-06-09 01:21:16 +0000371 fileTransport->setChunkSize(2 * 1024 * 1024);
372 fileTransport->setMaxEventSize(1024 * 16);
373
Konrad Grochowski240120c2014-11-18 11:33:31 +0100374 transportFactory =
375 boost::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Mark Sleee02385b2007-06-09 01:21:16 +0000376 }
377
Roger Meier611f90c2011-12-11 22:08:51 +0000378 boost::shared_ptr<Thread> serverThread;
379 boost::shared_ptr<Thread> serverThread2;
Mark Sleee02385b2007-06-09 01:21:16 +0000380
Mark Slee3e5d2d72007-06-15 01:45:56 +0000381 if (serverType == "simple") {
Mark Sleee02385b2007-06-09 01:21:16 +0000382
Konrad Grochowski240120c2014-11-18 11:33:31 +0100383 serverThread = threadFactory->newThread(boost::shared_ptr<TServer>(new TNonblockingServer(serviceProcessor, protocolFactory, port)));
384 serverThread2 = threadFactory->newThread(boost::shared_ptr<TServer>(new TNonblockingServer(serviceProcessor, protocolFactory, port+1)));
Mark Sleee02385b2007-06-09 01:21:16 +0000385
Mark Slee3e5d2d72007-06-15 01:45:56 +0000386 } else if (serverType == "thread-pool") {
Mark Sleee02385b2007-06-09 01:21:16 +0000387
Konrad Grochowski240120c2014-11-18 11:33:31 +0100388 boost::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
Mark Sleee02385b2007-06-09 01:21:16 +0000389
390 threadManager->threadFactory(threadFactory);
391 threadManager->start();
Konrad Grochowski240120c2014-11-18 11:33:31 +0100392 serverThread = threadFactory->newThread(boost::shared_ptr<TServer>(new TNonblockingServer(serviceProcessor, protocolFactory, port, threadManager)));
393 serverThread2 = threadFactory->newThread(boost::shared_ptr<TServer>(new TNonblockingServer(serviceProcessor, protocolFactory, port+1, threadManager)));
Mark Sleee02385b2007-06-09 01:21:16 +0000394 }
395
Mark Slee79b16942007-11-26 19:05:29 +0000396 cerr << "Starting the server on port " << port << " and " << (port + 1) << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000397 serverThread->start();
Mark Slee79b16942007-11-26 19:05:29 +0000398 serverThread2->start();
Mark Sleee02385b2007-06-09 01:21:16 +0000399
400 // If we aren't running clients, just wait forever for external clients
401
402 if (clientCount == 0) {
403 serverThread->join();
Mark Slee79b16942007-11-26 19:05:29 +0000404 serverThread2->join();
Mark Sleee02385b2007-06-09 01:21:16 +0000405 }
406 }
Jake Farrell5d02b802014-01-07 21:42:01 -0500407 THRIFT_SLEEP_SEC(1);
Mark Sleee02385b2007-06-09 01:21:16 +0000408
409 if (clientCount > 0) {
410
411 Monitor monitor;
412
413 size_t threadCount = 0;
414
Roger Meier611f90c2011-12-11 22:08:51 +0000415 set<boost::shared_ptr<Thread> > clientThreads;
Mark Sleee02385b2007-06-09 01:21:16 +0000416
Konrad Grochowski240120c2014-11-18 11:33:31 +0100417 if (callName == "echoVoid") { loopType = T_VOID;}
418 else if (callName == "echoByte") { loopType = T_BYTE;}
419 else if (callName == "echoI32") { loopType = T_I32;}
420 else if (callName == "echoI64") { loopType = T_I64;}
421 else if (callName == "echoString") { loopType = T_STRING;}
422 else {throw invalid_argument("Unknown service call "+callName);}
Mark Sleee02385b2007-06-09 01:21:16 +0000423
Jake Farrell5d02b802014-01-07 21:42:01 -0500424 for (uint32_t ix = 0; ix < clientCount; ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000425
Roger Meier611f90c2011-12-11 22:08:51 +0000426 boost::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port + (ix % 2)));
427 boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
428 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(framedSocket));
429 boost::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
Mark Sleee02385b2007-06-09 01:21:16 +0000430
Konrad Grochowski240120c2014-11-18 11:33:31 +0100431 clientThreads.insert(threadFactory->newThread(boost::shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Mark Sleee02385b2007-06-09 01:21:16 +0000432 }
433
Konrad Grochowski240120c2014-11-18 11:33:31 +0100434 for (std::set<boost::shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000435 (*thread)->start();
436 }
437
Roger Meier5f9614c2010-11-21 16:59:05 +0000438 int64_t time00;
439 int64_t time01;
Mark Sleee02385b2007-06-09 01:21:16 +0000440
Konrad Grochowski240120c2014-11-18 11:33:31 +0100441 {Synchronized s(monitor);
Mark Sleee02385b2007-06-09 01:21:16 +0000442 threadCount = clientCount;
443
Konrad Grochowski240120c2014-11-18 11:33:31 +0100444 cerr << "Launch "<< clientCount << " client threads" << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000445
Konrad Grochowski240120c2014-11-18 11:33:31 +0100446 time00 = Util::currentTime();
Mark Sleee02385b2007-06-09 01:21:16 +0000447
448 monitor.notifyAll();
449
Konrad Grochowski240120c2014-11-18 11:33:31 +0100450 while(threadCount > 0) {
Mark Sleee02385b2007-06-09 01:21:16 +0000451 monitor.wait();
452 }
453
Konrad Grochowski240120c2014-11-18 11:33:31 +0100454 time01 = Util::currentTime();
Mark Sleee02385b2007-06-09 01:21:16 +0000455 }
456
Roger Meier5f9614c2010-11-21 16:59:05 +0000457 int64_t firstTime = 9223372036854775807LL;
458 int64_t lastTime = 0;
Mark Sleee02385b2007-06-09 01:21:16 +0000459
460 double averageTime = 0;
Roger Meier5f9614c2010-11-21 16:59:05 +0000461 int64_t minTime = 9223372036854775807LL;
462 int64_t maxTime = 0;
Mark Sleee02385b2007-06-09 01:21:16 +0000463
Konrad Grochowski240120c2014-11-18 11:33:31 +0100464 for (set<boost::shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
Mark Sleee02385b2007-06-09 01:21:16 +0000465
Konrad Grochowski240120c2014-11-18 11:33:31 +0100466 boost::shared_ptr<ClientThread> client = boost::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
Mark Sleee02385b2007-06-09 01:21:16 +0000467
Roger Meier5f9614c2010-11-21 16:59:05 +0000468 int64_t delta = client->_endTime - client->_startTime;
Mark Sleee02385b2007-06-09 01:21:16 +0000469
470 assert(delta > 0);
471
Mark Slee3e5d2d72007-06-15 01:45:56 +0000472 if (client->_startTime < firstTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000473 firstTime = client->_startTime;
474 }
475
Mark Slee3e5d2d72007-06-15 01:45:56 +0000476 if (client->_endTime > lastTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000477 lastTime = client->_endTime;
478 }
479
Mark Slee3e5d2d72007-06-15 01:45:56 +0000480 if (delta < minTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000481 minTime = delta;
482 }
483
Mark Slee3e5d2d72007-06-15 01:45:56 +0000484 if (delta > maxTime) {
Mark Sleee02385b2007-06-09 01:21:16 +0000485 maxTime = delta;
486 }
487
Konrad Grochowski240120c2014-11-18 11:33:31 +0100488 averageTime+= delta;
Mark Sleee02385b2007-06-09 01:21:16 +0000489 }
490
491 averageTime /= clientCount;
492
Konrad Grochowski240120c2014-11-18 11:33:31 +0100493
494 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
Mark Sleee02385b2007-06-09 01:21:16 +0000495
496 count_map count = serviceHandler->getCount();
497 count_map::iterator iter;
498 for (iter = count.begin(); iter != count.end(); ++iter) {
499 printf("%s => %d\n", iter->first, iter->second);
500 }
501 cerr << "done." << endl;
502 }
503
504 return 0;
505}