1
// **********************************************************************
3
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
5
// This copy of Ice is licensed to you under the terms described in the
6
// ICE_LICENSE file included in this distribution.
8
// **********************************************************************
11
#include <Throughput.h>
20
class Callback : public IceUtil::Shared
28
void response(const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&)
32
void responseSS(const StringSeq&)
36
void responseTS(const StringDoubleSeq&)
40
void responseFS(const FixedSeq&)
44
void exception(const ::Ice::Exception& ex)
50
typedef IceUtil::Handle<Callback> CallbackPtr;
52
class ThroughputClient : public Ice::Application
57
virtual int run(int, char*[]);
65
main(int argc, char* argv[])
68
return app.main(argc, argv, "config.client");
71
ThroughputClient::ThroughputClient() :
73
// Since this is an interactive demo we don't want any signal
76
Ice::Application(Ice::NoSignalHandling)
81
ThroughputClient::run(int argc, char* argv[])
85
cerr << appName() << ": too many arguments" << endl;
89
ThroughputPrx throughput = ThroughputPrx::checkedCast(communicator()->propertyToProxy("Throughput.Proxy"));
92
cerr << argv[0] << ": invalid proxy" << endl;
96
ThroughputPrx throughputOneway = ThroughputPrx::uncheckedCast(throughput->ice_oneway());
98
ByteSeq byteSeq(ByteSeqSize);
99
pair<const Ice::Byte*, const Ice::Byte*> byteArr;
100
byteArr.first = &byteSeq[0];
101
byteArr.second = byteArr.first + byteSeq.size();
103
StringSeq stringSeq(StringSeqSize, "hello");
105
StringDoubleSeq structSeq(StringDoubleSeqSize);
107
for(i = 0; i < StringDoubleSeqSize; ++i)
109
structSeq[i].s = "hello";
110
structSeq[i].d = 3.14;
113
FixedSeq fixedSeq(FixedSeqSize);
114
for(i = 0; i < FixedSeqSize; ++i)
121
throughput->ice_ping(); // Initial ping to setup the connection.
126
// By default use byte sequence.
128
char currentType = '1';
129
int seqSize = ByteSeqSize;
130
// The maximum number of outstanding requests. -1 means
131
// unlimited. If the number of oustanding requests is unlimited
132
// and the server is slower than the client in processing the
133
// requests, high memory consumption will result.
134
int maxOutstanding = 2;
136
CallbackPtr cb = new Callback;
138
Callback_Throughput_echoByteSeqPtr byteSeqCB = newCallback_Throughput_echoByteSeq(
139
cb, &Callback::response, &Callback::exception);
140
Callback_Throughput_echoStringSeqPtr stringSeqCB = newCallback_Throughput_echoStringSeq(
141
cb, &Callback::responseSS, &Callback::exception);
142
Callback_Throughput_echoStructSeqPtr structSeqCB = newCallback_Throughput_echoStructSeq(
143
cb, &Callback::responseTS, &Callback::exception);
144
Callback_Throughput_echoFixedSeqPtr fixedSeqCB = newCallback_Throughput_echoFixedSeq(
145
cb, &Callback::responseFS, &Callback::exception);
155
IceUtil::Time tm = IceUtil::Time::now(IceUtil::Time::Monotonic);
156
const int repetitions = 1000;
160
if(maxOutstanding == -1)
163
cout << "outstanding requests are now limited to 2." << endl;
168
cout << "outstanding requests are now unlimited." << endl;
171
else if(c == '1' || c == '2' || c == '3' || c == '4')
178
cout << "using byte sequences" << endl;
179
seqSize = ByteSeqSize;
185
cout << "using string sequences" << endl;
186
seqSize = StringSeqSize;
192
cout << "using variable-length struct sequences" << endl;
193
seqSize = StringDoubleSeqSize;
199
cout << "using fixed-length struct sequences" << endl;
200
seqSize = FixedSeqSize;
207
cout << "sending and receiving";
209
cout << ' ' << repetitions;
226
cout << " variable-length struct";
232
cout << " fixed-length struct";
236
cout << " sequences of size " << seqSize;
238
cout << "..." << endl;
240
list<Ice::AsyncResultPtr> results;
241
for(int i = 0; i < repetitions; ++i)
243
// Start the AMI request.
244
Ice::AsyncResultPtr r;
248
r = throughput->begin_echoByteSeq(byteArr, byteSeqCB);
252
r = throughput->begin_echoStringSeq(stringSeq, stringSeqCB);
256
r = throughput->begin_echoStructSeq(structSeq, structSeqCB);
260
r = throughput->begin_echoFixedSeq(fixedSeq, fixedSeqCB);
263
// For flow control purposes we want to restrict
264
// the number of sending messages to one. This
265
// avoids unnecessarily accumulating buffers in
266
// the Ice runtime, keeping memory usage low.
268
results.push_back(r);
270
// Remove any completed requests from the list of
272
list<Ice::AsyncResultPtr>::iterator p = results.begin();
273
while(p != results.end())
275
if((*p)->isCompleted())
277
p = results.erase(p);
285
// This avoids too many outstanding requests. This
286
// is desirable if the server doesn't limit the
287
// number of threads, or the server process
288
// requests slower than then client can send them.
289
while(maxOutstanding != -1 && static_cast<int>(results.size()) > maxOutstanding)
293
r->waitForCompleted();
296
// Before we're complete we must wait for all
297
// responses to be received.
298
while(!results.empty())
300
Ice::AsyncResultPtr r = results.front();
302
r->waitForCompleted();
305
tm = IceUtil::Time::now(IceUtil::Time::Monotonic) - tm;
306
cout << "time for " << repetitions << " sequences: " << tm * 1000 << "ms" << endl;
307
cout << "time per sequence: " << tm * 1000 / repetitions << "ms" << endl;
318
wireSize = static_cast<int>(stringSeq[0].size());
323
wireSize = static_cast<int>(structSeq[0].s.size());
324
wireSize += 8; // Size of double on the wire.
329
wireSize = 16; // Size of two ints and a double on the wire.
333
double mbit = repetitions * seqSize * wireSize * 8.0 / tm.toMicroSeconds();
338
cout << "throughput: " << setprecision(5) << mbit << "Mbps" << endl;
342
throughput->shutdown();
354
cout << "unknown command `" << c << "'" << endl;
358
catch(const Ice::Exception& ex)
363
while(cin.good() && c != 'x');
369
ThroughputClient::menu()
374
"toggle type of data to send:\n"
375
"1: sequence of bytes (default)\n"
376
"2: sequence of strings (\"hello\")\n"
377
"3: sequence of structs with a string (\"hello\") and a double\n"
378
"4: sequence of structs with two ints and a double\n"
379
"o: toggle the limit of outstanding requests\n"
381
"select test to run:\n"
382
"e: Echo (send and receive) sequence\n"
385
"s: shutdown server\n"