blob: dfe8350724dbb70f9082d1f3a56270bc65b338be [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/transport/TServerSocket.h>
30#include <thrift/transport/TSocket.h>
31#include <thrift/transport/TTransportUtils.h>
32#include <thrift/transport/TFileTransport.h>
Roger Meier33eaa0f2012-04-13 09:13:13 +000033#include <thrift/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>
Mark Sleeb9ff32a2006-11-16 01:00:24 +000041#include <map>
Jake Farrell5d02b802014-01-07 21:42:01 -050042#if _WIN32
43 #include <thrift/windows/TWinsockSingleton.h>
44#endif
Mark Sleeb9ff32a2006-11-16 01:00:24 +000045
Marc Slemko3ea00332006-08-17 01:11:13 +000046using namespace std;
47
T Jake Lucianib5e62212009-01-31 22:36:20 +000048using namespace apache::thrift;
49using namespace apache::thrift::protocol;
50using namespace apache::thrift::transport;
51using namespace apache::thrift::server;
52using namespace apache::thrift::concurrency;
Marc Slemko3ea00332006-08-17 01:11:13 +000053
54using namespace test::stress;
55
Mark Sleeb9ff32a2006-11-16 01:00:24 +000056struct eqstr {
57 bool operator()(const char* s1, const char* s2) const {
58 return strcmp(s1, s2) == 0;
59 }
60};
61
62struct ltstr {
63 bool operator()(const char* s1, const char* s2) const {
64 return strcmp(s1, s2) < 0;
65 }
66};
67
68
David Reiss0c90f6f2008-02-06 22:18:40 +000069// typedef hash_map<const char*, int, hash<const char*>, eqstr> count_map;
70typedef map<const char*, int, ltstr> count_map;
Mark Sleeb9ff32a2006-11-16 01:00:24 +000071
Aditya Agarwal3950f472006-10-11 02:50:15 +000072class Server : public ServiceIf {
Marc Slemko3ea00332006-08-17 01:11:13 +000073 public:
Mark Sleeb9ff32a2006-11-16 01:00:24 +000074 Server() {}
75
76 void count(const char* method) {
David Reiss46379902008-02-04 19:23:57 +000077 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000078 int ct = counts_[method];
79 counts_[method] = ++ct;
80 }
81
82 void echoVoid() {
83 count("echoVoid");
84 return;
85 }
86
87 count_map getCount() {
David Reiss46379902008-02-04 19:23:57 +000088 Guard m(lock_);
Mark Sleeb9ff32a2006-11-16 01:00:24 +000089 return counts_;
90 }
91
Mark Slee739dbe52007-02-01 22:55:30 +000092 int8_t echoByte(const int8_t arg) {return arg;}
93 int32_t echoI32(const int32_t arg) {return arg;}
94 int64_t echoI64(const int64_t arg) {return arg;}
95 void echoString(string& out, const string &arg) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000096 if (arg != "hello") {
Roger Meiera8cef6e2011-07-17 18:55:59 +000097 T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
Aditya Agarwale9ef8d72006-12-08 23:52:57 +000098 }
Mark Slee739dbe52007-02-01 22:55:30 +000099 out = arg;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000100 }
Mark Slee739dbe52007-02-01 22:55:30 +0000101 void echoList(vector<int8_t> &out, const vector<int8_t> &arg) { out = arg; }
102 void echoSet(set<int8_t> &out, const set<int8_t> &arg) { out = arg; }
103 void echoMap(map<int8_t, int8_t> &out, const map<int8_t, int8_t> &arg) { out = arg; }
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000104
105private:
106 count_map counts_;
107 Mutex lock_;
108
Marc Slemko3ea00332006-08-17 01:11:13 +0000109};
110
111class ClientThread: public Runnable {
112public:
113
Roger Meier611f90c2011-12-11 22:08:51 +0000114 ClientThread(boost::shared_ptr<TTransport>transport, boost::shared_ptr<ServiceClient> client, Monitor& monitor, size_t& workerCount, size_t loopCount, TType loopType) :
Marc Slemko3ea00332006-08-17 01:11:13 +0000115 _transport(transport),
116 _client(client),
117 _monitor(monitor),
118 _workerCount(workerCount),
Marc Slemkod97eb612006-08-24 23:37:36 +0000119 _loopCount(loopCount),
120 _loopType(loopType)
Marc Slemko3ea00332006-08-17 01:11:13 +0000121 {}
122
123 void run() {
124
David Reiss0c90f6f2008-02-06 22:18:40 +0000125 // Wait for all worker threads to start
Marc Slemko3ea00332006-08-17 01:11:13 +0000126
127 {Synchronized s(_monitor);
David Reiss0c90f6f2008-02-06 22:18:40 +0000128 while(_workerCount == 0) {
129 _monitor.wait();
130 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000131 }
132
133 _startTime = Util::currentTime();
134
135 _transport->open();
136
Marc Slemkod97eb612006-08-24 23:37:36 +0000137 switch(_loopType) {
138 case T_VOID: loopEchoVoid(); break;
139 case T_BYTE: loopEchoByte(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000140 case T_I32: loopEchoI32(); break;
141 case T_I64: loopEchoI64(); break;
Marc Slemkod97eb612006-08-24 23:37:36 +0000142 case T_STRING: loopEchoString(); break;
143 default: cerr << "Unexpected loop type" << _loopType << endl; break;
Marc Slemko3ea00332006-08-17 01:11:13 +0000144 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000145
Marc Slemko3ea00332006-08-17 01:11:13 +0000146 _endTime = Util::currentTime();
147
148 _transport->close();
David Reiss0c90f6f2008-02-06 22:18:40 +0000149
Marc Slemko3ea00332006-08-17 01:11:13 +0000150 _done = true;
David Reiss0c90f6f2008-02-06 22:18:40 +0000151
Marc Slemko3ea00332006-08-17 01:11:13 +0000152 {Synchronized s(_monitor);
153
154 _workerCount--;
David Reiss0c90f6f2008-02-06 22:18:40 +0000155
Mark Slee3e5d2d72007-06-15 01:45:56 +0000156 if (_workerCount == 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000157
158 _monitor.notify();
Marc Slemko3ea00332006-08-17 01:11:13 +0000159 }
160 }
161 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000162
163 void loopEchoVoid() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000164 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000165 _client->echoVoid();
166 }
167 }
168
169 void loopEchoByte() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000170 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000171 int8_t arg = 1;
172 int8_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000173 result =_client->echoByte(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500174 (void)result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000175 assert(result == arg);
176 }
177 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000178
Marc Slemkod97eb612006-08-24 23:37:36 +0000179 void loopEchoI32() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000180 for (size_t ix = 0; ix < _loopCount; ix++) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000181 int32_t arg = 1;
182 int32_t result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000183 result =_client->echoI32(arg);
Jake Farrell5d02b802014-01-07 21:42:01 -0500184 (void)result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000185 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);
Jake Farrell5d02b802014-01-07 21:42:01 -0500194 (void)result;
Marc Slemkod97eb612006-08-24 23:37:36 +0000195 assert(result == arg);
196 }
197 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000198
Marc Slemkod97eb612006-08-24 23:37:36 +0000199 void loopEchoString() {
Mark Slee3e5d2d72007-06-15 01:45:56 +0000200 for (size_t ix = 0; ix < _loopCount; ix++) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000201 string arg = "hello";
202 string result;
Mark Slee739dbe52007-02-01 22:55:30 +0000203 _client->echoString(result, arg);
Marc Slemkod97eb612006-08-24 23:37:36 +0000204 assert(result == arg);
205 }
206 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000207
Roger Meier611f90c2011-12-11 22:08:51 +0000208 boost::shared_ptr<TTransport> _transport;
209 boost::shared_ptr<ServiceClient> _client;
Marc Slemko3ea00332006-08-17 01:11:13 +0000210 Monitor& _monitor;
211 size_t& _workerCount;
212 size_t _loopCount;
Marc Slemkod97eb612006-08-24 23:37:36 +0000213 TType _loopType;
Roger Meier5f9614c2010-11-21 16:59:05 +0000214 int64_t _startTime;
215 int64_t _endTime;
Marc Slemko3ea00332006-08-17 01:11:13 +0000216 bool _done;
217 Monitor _sleep;
218};
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000219
Jake Farrell5d02b802014-01-07 21:42:01 -0500220class TStartObserver : public apache::thrift::server::TServerEventHandler
221{
222public:
223 TStartObserver() : awake_(false) {}
224 virtual void preServe()
225 {
226 apache::thrift::concurrency::Synchronized s(m_);
227 awake_ = true;
228 m_.notifyAll();
229 }
230 void waitForService()
231 {
232 apache::thrift::concurrency::Synchronized s(m_);
233 while(!awake_)
234 m_.waitForever();
235 }
236 private:
237 apache::thrift::concurrency::Monitor m_;
238 bool awake_;
239};
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000240
Marc Slemko3ea00332006-08-17 01:11:13 +0000241int main(int argc, char **argv) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500242#if _WIN32
243 transport::TWinsockSingleton::create();
244#endif
Marc Slemko3ea00332006-08-17 01:11:13 +0000245
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000246 int port = 9091;
Marc Slemko3ea00332006-08-17 01:11:13 +0000247 string serverType = "thread-pool";
248 string protocolType = "binary";
249 size_t workerCount = 4;
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000250 size_t clientCount = 20;
251 size_t loopCount = 50000;
Marc Slemkod97eb612006-08-24 23:37:36 +0000252 TType loopType = T_VOID;
253 string callName = "echoVoid";
Marc Slemkob09f5882006-08-23 22:03:34 +0000254 bool runServer = true;
Aditya Agarwal3950f472006-10-11 02:50:15 +0000255 bool logRequests = false;
256 string requestLogPath = "./requestlog.tlog";
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000257 bool replayRequests = false;
Marc Slemko3ea00332006-08-17 01:11:13 +0000258
Marc Slemkob09f5882006-08-23 22:03:34 +0000259 ostringstream usage;
Marc Slemko3ea00332006-08-17 01:11:13 +0000260
261 usage <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000262 argv[0] << " [--port=<port number>] [--server] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--clients=<client-count>] [--loop=<loop-count>]" << endl <<
263 "\tclients Number of client threads to create - 0 implies no clients, i.e. server only. Default is " << clientCount << endl <<
264 "\thelp Prints this help text." << endl <<
Marc Slemkod97eb612006-08-24 23:37:36 +0000265 "\tcall Service method to call. Default is " << callName << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000266 "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl <<
267 "\tport The port the server and clients should bind to for thrift network connections. Default is " << port << endl <<
268 "\tserver Run the Thrift server in this process. Default is " << runServer << endl <<
269 "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl <<
270 "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl <<
Aditya Agarwal3950f472006-10-11 02:50:15 +0000271 "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000272 "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
Marc Slemkob09f5882006-08-23 22:03:34 +0000273 "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000274
275
Marc Slemko3ea00332006-08-17 01:11:13 +0000276 map<string, string> args;
David Reiss0c90f6f2008-02-06 22:18:40 +0000277
Mark Slee3e5d2d72007-06-15 01:45:56 +0000278 for (int ix = 1; ix < argc; ix++) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000279
280 string arg(argv[ix]);
281
Mark Slee3e5d2d72007-06-15 01:45:56 +0000282 if (arg.compare(0,2, "--") == 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000283
284 size_t end = arg.find_first_of("=", 2);
285
Marc Slemko056f9ba2006-08-17 02:59:05 +0000286 string key = string(arg, 2, end - 2);
287
Mark Slee3e5d2d72007-06-15 01:45:56 +0000288 if (end != string::npos) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000289 args[key] = string(arg, end + 1);
Marc Slemko3ea00332006-08-17 01:11:13 +0000290 } else {
David Reiss0c90f6f2008-02-06 22:18:40 +0000291 args[key] = "true";
Marc Slemko3ea00332006-08-17 01:11:13 +0000292 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000293 } else {
294 throw invalid_argument("Unexcepted command line token: "+arg);
295 }
296 }
297
298 try {
299
Mark Slee3e5d2d72007-06-15 01:45:56 +0000300 if (!args["clients"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000301 clientCount = atoi(args["clients"].c_str());
302 }
303
Mark Slee3e5d2d72007-06-15 01:45:56 +0000304 if (!args["help"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000305 cerr << usage.str();
306 return 0;
307 }
308
Mark Slee3e5d2d72007-06-15 01:45:56 +0000309 if (!args["loop"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000310 loopCount = atoi(args["loop"].c_str());
311 }
312
Mark Slee3e5d2d72007-06-15 01:45:56 +0000313 if (!args["call"].empty()) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000314 callName = args["call"];
315 }
316
Mark Slee3e5d2d72007-06-15 01:45:56 +0000317 if (!args["port"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000318 port = atoi(args["port"].c_str());
319 }
320
Mark Slee3e5d2d72007-06-15 01:45:56 +0000321 if (!args["server"].empty()) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000322 runServer = args["server"] == "true";
323 }
324
Mark Slee3e5d2d72007-06-15 01:45:56 +0000325 if (!args["log-request"].empty()) {
Aditya Agarwal3950f472006-10-11 02:50:15 +0000326 logRequests = args["log-request"] == "true";
327 }
328
Mark Slee3e5d2d72007-06-15 01:45:56 +0000329 if (!args["replay-request"].empty()) {
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000330 replayRequests = args["replay-request"] == "true";
331 }
332
Mark Slee3e5d2d72007-06-15 01:45:56 +0000333 if (!args["server-type"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000334 serverType = args["server-type"];
David Reiss0c90f6f2008-02-06 22:18:40 +0000335
Mark Slee3e5d2d72007-06-15 01:45:56 +0000336 if (serverType == "simple") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000337
Mark Slee3e5d2d72007-06-15 01:45:56 +0000338 } else if (serverType == "thread-pool") {
Marc Slemko3ea00332006-08-17 01:11:13 +0000339
Mark Slee3e5d2d72007-06-15 01:45:56 +0000340 } else if (serverType == "threaded") {
Mark Slee739dbe52007-02-01 22:55:30 +0000341
Marc Slemko3ea00332006-08-17 01:11:13 +0000342 } else {
343
David Reiss0c90f6f2008-02-06 22:18:40 +0000344 throw invalid_argument("Unknown server type "+serverType);
Marc Slemko3ea00332006-08-17 01:11:13 +0000345 }
346 }
347
Mark Slee3e5d2d72007-06-15 01:45:56 +0000348 if (!args["workers"].empty()) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000349 workerCount = atoi(args["workers"].c_str());
350 }
351
Roger Meierbb09f442011-05-31 20:35:37 +0000352 } catch(std::exception& e) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000353 cerr << e.what() << endl;
Jake Farrell5d02b802014-01-07 21:42:01 -0500354 cerr << usage.str();
Marc Slemko3ea00332006-08-17 01:11:13 +0000355 }
356
Roger Meier611f90c2011-12-11 22:08:51 +0000357 boost::shared_ptr<PlatformThreadFactory> threadFactory = boost::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
Marc Slemko3ea00332006-08-17 01:11:13 +0000358
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000359 // Dispatcher
Roger Meier611f90c2011-12-11 22:08:51 +0000360 boost::shared_ptr<Server> serviceHandler(new Server());
Marc Slemko3ea00332006-08-17 01:11:13 +0000361
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000362 if (replayRequests) {
Roger Meier611f90c2011-12-11 22:08:51 +0000363 boost::shared_ptr<Server> serviceHandler(new Server());
364 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
David Reiss0c90f6f2008-02-06 22:18:40 +0000365
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000366 // Transports
Roger Meier611f90c2011-12-11 22:08:51 +0000367 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000368 fileTransport->setChunkSize(2 * 1024 * 1024);
369 fileTransport->setMaxEventSize(1024 * 16);
370 fileTransport->seekToEnd();
371
372 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000373 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000374
375 TFileProcessor fileProcessor(serviceProcessor,
376 protocolFactory,
377 fileTransport);
378
David Reiss0c90f6f2008-02-06 22:18:40 +0000379 fileProcessor.process(0, true);
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000380 exit(0);
381 }
382
383
Mark Slee3e5d2d72007-06-15 01:45:56 +0000384 if (runServer) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000385
Roger Meier611f90c2011-12-11 22:08:51 +0000386 boost::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
Marc Slemko3ea00332006-08-17 01:11:13 +0000387
Marc Slemkob09f5882006-08-23 22:03:34 +0000388 // Transport
Roger Meier611f90c2011-12-11 22:08:51 +0000389 boost::shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
Marc Slemko3ea00332006-08-17 01:11:13 +0000390
Aditya Agarwal3950f472006-10-11 02:50:15 +0000391 // Transport Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000392 boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000393
Mark Sleed7173472006-10-25 19:52:10 +0000394 // Protocol Factory
Roger Meier611f90c2011-12-11 22:08:51 +0000395 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Aditya Agarwal3950f472006-10-11 02:50:15 +0000396
397 if (logRequests) {
398 // initialize the log file
Roger Meier611f90c2011-12-11 22:08:51 +0000399 boost::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
Aditya Agarwale9ef8d72006-12-08 23:52:57 +0000400 fileTransport->setChunkSize(2 * 1024 * 1024);
401 fileTransport->setMaxEventSize(1024 * 16);
David Reiss0c90f6f2008-02-06 22:18:40 +0000402
403 transportFactory =
Roger Meier611f90c2011-12-11 22:08:51 +0000404 boost::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
Aditya Agarwal3950f472006-10-11 02:50:15 +0000405 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000406
Jake Farrell5d02b802014-01-07 21:42:01 -0500407 boost::shared_ptr<TServer> server;
Marc Slemko3ea00332006-08-17 01:11:13 +0000408
Mark Slee3e5d2d72007-06-15 01:45:56 +0000409 if (serverType == "simple") {
David Reiss0c90f6f2008-02-06 22:18:40 +0000410
Jake Farrell5d02b802014-01-07 21:42:01 -0500411 server.reset(new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory));
David Reiss0c90f6f2008-02-06 22:18:40 +0000412
Mark Slee739dbe52007-02-01 22:55:30 +0000413 } else if (serverType == "threaded") {
414
Jake Farrell5d02b802014-01-07 21:42:01 -0500415 server.reset(new TThreadedServer(serviceProcessor, serverSocket, transportFactory, protocolFactory));
David Reiss0c90f6f2008-02-06 22:18:40 +0000416
Mark Slee3e5d2d72007-06-15 01:45:56 +0000417 } else if (serverType == "thread-pool") {
Marc Slemkob09f5882006-08-23 22:03:34 +0000418
Roger Meier611f90c2011-12-11 22:08:51 +0000419 boost::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
Marc Slemkob09f5882006-08-23 22:03:34 +0000420
421 threadManager->threadFactory(threadFactory);
David Reiss0c90f6f2008-02-06 22:18:40 +0000422 threadManager->start();
Jake Farrell5d02b802014-01-07 21:42:01 -0500423 server.reset(new TThreadPoolServer(serviceProcessor, serverSocket, transportFactory, protocolFactory, threadManager));
Marc Slemkob09f5882006-08-23 22:03:34 +0000424 }
425
Jake Farrell5d02b802014-01-07 21:42:01 -0500426 boost::shared_ptr<TStartObserver> observer(new TStartObserver);
427 server->setServerEventHandler(observer);
428 boost::shared_ptr<Thread> serverThread = threadFactory->newThread(server);
429
Marc Slemkob09f5882006-08-23 22:03:34 +0000430 cerr << "Starting the server on port " << port << endl;
431
432 serverThread->start();
Jake Farrell5d02b802014-01-07 21:42:01 -0500433 observer->waitForService();
David Reiss0c90f6f2008-02-06 22:18:40 +0000434
Marc Slemkob09f5882006-08-23 22:03:34 +0000435 // If we aren't running clients, just wait forever for external clients
Mark Sleed7173472006-10-25 19:52:10 +0000436 if (clientCount == 0) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000437 serverThread->join();
438 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000439 }
440
Mark Sleed7173472006-10-25 19:52:10 +0000441 if (clientCount > 0) {
Marc Slemko3ea00332006-08-17 01:11:13 +0000442
Marc Slemkob09f5882006-08-23 22:03:34 +0000443 Monitor monitor;
Marc Slemko3ea00332006-08-17 01:11:13 +0000444
Marc Slemkob09f5882006-08-23 22:03:34 +0000445 size_t threadCount = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000446
Roger Meier611f90c2011-12-11 22:08:51 +0000447 set<boost::shared_ptr<Thread> > clientThreads;
Marc Slemko3ea00332006-08-17 01:11:13 +0000448
Mark Slee3e5d2d72007-06-15 01:45:56 +0000449 if (callName == "echoVoid") { loopType = T_VOID;}
450 else if (callName == "echoByte") { loopType = T_BYTE;}
451 else if (callName == "echoI32") { loopType = T_I32;}
452 else if (callName == "echoI64") { loopType = T_I64;}
453 else if (callName == "echoString") { loopType = T_STRING;}
Marc Slemkod97eb612006-08-24 23:37:36 +0000454 else {throw invalid_argument("Unknown service call "+callName);}
455
Mark Slee3e5d2d72007-06-15 01:45:56 +0000456 for (size_t ix = 0; ix < clientCount; ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000457
Roger Meier611f90c2011-12-11 22:08:51 +0000458 boost::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
459 boost::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
460 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
461 boost::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
David Reiss0c90f6f2008-02-06 22:18:40 +0000462
Roger Meier611f90c2011-12-11 22:08:51 +0000463 clientThreads.insert(threadFactory->newThread(boost::shared_ptr<ClientThread>(new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
Marc Slemkob09f5882006-08-23 22:03:34 +0000464 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000465
Roger Meier611f90c2011-12-11 22:08:51 +0000466 for (std::set<boost::shared_ptr<Thread> >::const_iterator thread = clientThreads.begin(); thread != clientThreads.end(); thread++) {
Marc Slemkob09f5882006-08-23 22:03:34 +0000467 (*thread)->start();
468 }
Marc Slemko3ea00332006-08-17 01:11:13 +0000469
Roger Meier5f9614c2010-11-21 16:59:05 +0000470 int64_t time00;
471 int64_t time01;
David Reiss0c90f6f2008-02-06 22:18:40 +0000472
Marc Slemkob09f5882006-08-23 22:03:34 +0000473 {Synchronized s(monitor);
474 threadCount = clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000475
Marc Slemkob09f5882006-08-23 22:03:34 +0000476 cerr << "Launch "<< clientCount << " client threads" << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000477
Marc Slemkob09f5882006-08-23 22:03:34 +0000478 time00 = Util::currentTime();
David Reiss0c90f6f2008-02-06 22:18:40 +0000479
Marc Slemkob09f5882006-08-23 22:03:34 +0000480 monitor.notifyAll();
David Reiss0c90f6f2008-02-06 22:18:40 +0000481
Marc Slemkob09f5882006-08-23 22:03:34 +0000482 while(threadCount > 0) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000483 monitor.wait();
Marc Slemkob09f5882006-08-23 22:03:34 +0000484 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000485
Marc Slemkob09f5882006-08-23 22:03:34 +0000486 time01 = Util::currentTime();
Marc Slemko3ea00332006-08-17 01:11:13 +0000487 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000488
Roger Meier5f9614c2010-11-21 16:59:05 +0000489 int64_t firstTime = 9223372036854775807LL;
490 int64_t lastTime = 0;
Marc Slemko3ea00332006-08-17 01:11:13 +0000491
Marc Slemkob09f5882006-08-23 22:03:34 +0000492 double averageTime = 0;
Roger Meier5f9614c2010-11-21 16:59:05 +0000493 int64_t minTime = 9223372036854775807LL;
494 int64_t maxTime = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000495
Roger Meier611f90c2011-12-11 22:08:51 +0000496 for (set<boost::shared_ptr<Thread> >::iterator ix = clientThreads.begin(); ix != clientThreads.end(); ix++) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000497
Jake Farrell5d02b802014-01-07 21:42:01 -0500498 boost::shared_ptr<ClientThread> client = boost::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
David Reiss0c90f6f2008-02-06 22:18:40 +0000499
Roger Meier5f9614c2010-11-21 16:59:05 +0000500 int64_t delta = client->_endTime - client->_startTime;
David Reiss0c90f6f2008-02-06 22:18:40 +0000501
Marc Slemkob09f5882006-08-23 22:03:34 +0000502 assert(delta > 0);
Marc Slemko056f9ba2006-08-17 02:59:05 +0000503
Mark Slee3e5d2d72007-06-15 01:45:56 +0000504 if (client->_startTime < firstTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000505 firstTime = client->_startTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000506 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000507
Mark Slee3e5d2d72007-06-15 01:45:56 +0000508 if (client->_endTime > lastTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000509 lastTime = client->_endTime;
Marc Slemkob09f5882006-08-23 22:03:34 +0000510 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000511
Mark Slee3e5d2d72007-06-15 01:45:56 +0000512 if (delta < minTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000513 minTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000514 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000515
Mark Slee3e5d2d72007-06-15 01:45:56 +0000516 if (delta > maxTime) {
David Reiss0c90f6f2008-02-06 22:18:40 +0000517 maxTime = delta;
Marc Slemkob09f5882006-08-23 22:03:34 +0000518 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000519
Marc Slemkob09f5882006-08-23 22:03:34 +0000520 averageTime+= delta;
521 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000522
Marc Slemkob09f5882006-08-23 22:03:34 +0000523 averageTime /= clientCount;
David Reiss0c90f6f2008-02-06 22:18:40 +0000524
525
Marc Slemkob09f5882006-08-23 22:03:34 +0000526 cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +0000527
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000528 count_map count = serviceHandler->getCount();
529 count_map::iterator iter;
530 for (iter = count.begin(); iter != count.end(); ++iter) {
531 printf("%s => %d\n", iter->first, iter->second);
532 }
Marc Slemkob09f5882006-08-23 22:03:34 +0000533 cerr << "done." << endl;
Marc Slemko056f9ba2006-08-17 02:59:05 +0000534 }
Marc Slemko056f9ba2006-08-17 02:59:05 +0000535
Marc Slemko3ea00332006-08-17 01:11:13 +0000536 return 0;
537}