~ubuntu-branches/ubuntu/quantal/zeroc-ice/quantal

« back to all changes in this revision

Viewing changes to cpp/demo/Ice/interleaved/Client.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cleto Martin Angelina
  • Date: 2011-04-25 18:44:24 UTC
  • mfrom: (6.1.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110425184424-sep9i9euu434vq4c
Tags: 3.4.1-7
* Bug fix: "libdb5.1-java.jar was renamed to db.jar", thanks to Ondřej
  Surý (Closes: #623555).
* Bug fix: "causes noise in php5", thanks to Jayen Ashar (Closes:
  #623533).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// **********************************************************************
 
2
//
 
3
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
 
4
//
 
5
// This copy of Ice is licensed to you under the terms described in the
 
6
// ICE_LICENSE file included in this distribution.
 
7
//
 
8
// **********************************************************************
 
9
 
 
10
#include <Ice/Ice.h>
 
11
#include <Throughput.h>
 
12
 
 
13
#include <iomanip>
 
14
 
 
15
#include <list>
 
16
 
 
17
using namespace std;
 
18
using namespace Demo;
 
19
 
 
20
class Callback : public IceUtil::Shared
 
21
{
 
22
public:
 
23
 
 
24
    Callback()
 
25
    {
 
26
    }
 
27
 
 
28
    void response(const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&)
 
29
    {
 
30
    }
 
31
 
 
32
    void responseSS(const StringSeq&)
 
33
    {
 
34
    }
 
35
 
 
36
    void responseTS(const StringDoubleSeq&)
 
37
    {
 
38
    }
 
39
 
 
40
    void responseFS(const FixedSeq&)
 
41
    {
 
42
    }
 
43
 
 
44
    void exception(const ::Ice::Exception& ex)
 
45
    {
 
46
        cerr << ex << endl;
 
47
    }
 
48
};
 
49
 
 
50
typedef IceUtil::Handle<Callback> CallbackPtr;
 
51
 
 
52
class ThroughputClient : public Ice::Application
 
53
{
 
54
public:
 
55
 
 
56
    ThroughputClient();
 
57
    virtual int run(int, char*[]);
 
58
 
 
59
private:
 
60
 
 
61
    void menu();
 
62
};
 
63
 
 
64
int
 
65
main(int argc, char* argv[])
 
66
{
 
67
    ThroughputClient app;
 
68
    return app.main(argc, argv, "config.client");
 
69
}
 
70
 
 
71
ThroughputClient::ThroughputClient() :
 
72
    //
 
73
    // Since this is an interactive demo we don't want any signal
 
74
    // handling.
 
75
    //
 
76
    Ice::Application(Ice::NoSignalHandling)
 
77
{
 
78
}
 
79
 
 
80
int
 
81
ThroughputClient::run(int argc, char* argv[])
 
82
{
 
83
    if(argc > 1)
 
84
    {
 
85
        cerr << appName() << ": too many arguments" << endl;
 
86
        return EXIT_FAILURE;
 
87
    }
 
88
 
 
89
    ThroughputPrx throughput = ThroughputPrx::checkedCast(communicator()->propertyToProxy("Throughput.Proxy"));
 
90
    if(!throughput)
 
91
    {
 
92
        cerr << argv[0] << ": invalid proxy" << endl;
 
93
        return EXIT_FAILURE;
 
94
    }
 
95
 
 
96
    ThroughputPrx throughputOneway = ThroughputPrx::uncheckedCast(throughput->ice_oneway());
 
97
 
 
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();
 
102
 
 
103
    StringSeq stringSeq(StringSeqSize, "hello");
 
104
 
 
105
    StringDoubleSeq structSeq(StringDoubleSeqSize);
 
106
    int i;
 
107
    for(i = 0; i < StringDoubleSeqSize; ++i)
 
108
    {
 
109
        structSeq[i].s = "hello";
 
110
        structSeq[i].d = 3.14;
 
111
    }
 
112
 
 
113
    FixedSeq fixedSeq(FixedSeqSize);
 
114
    for(i = 0; i < FixedSeqSize; ++i)
 
115
    {
 
116
        fixedSeq[i].i = 0;
 
117
        fixedSeq[i].j = 0;
 
118
        fixedSeq[i].d = 0;
 
119
    }
 
120
 
 
121
    throughput->ice_ping(); // Initial ping to setup the connection.
 
122
 
 
123
    menu();
 
124
 
 
125
    //
 
126
    // By default use byte sequence.
 
127
    //
 
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;
 
135
 
 
136
    CallbackPtr cb = new Callback;
 
137
 
 
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);
 
146
 
 
147
    char c;
 
148
    do
 
149
    {
 
150
        try
 
151
        {
 
152
            cout << "==> ";
 
153
            cin >> c;
 
154
 
 
155
            IceUtil::Time tm = IceUtil::Time::now(IceUtil::Time::Monotonic);
 
156
            const int repetitions = 1000;
 
157
 
 
158
            if(c == 'o')
 
159
            {
 
160
                if(maxOutstanding == -1)
 
161
                {
 
162
                    maxOutstanding = 2;
 
163
                    cout << "outstanding requests are now limited to 2." << endl;
 
164
                }
 
165
                else
 
166
                {
 
167
                    maxOutstanding = -1;
 
168
                    cout << "outstanding requests are now unlimited." << endl;
 
169
                }
 
170
            }
 
171
            else if(c == '1' || c == '2' || c == '3' || c == '4')
 
172
            {
 
173
                currentType = c;
 
174
                switch(c)
 
175
                {
 
176
                    case '1':
 
177
                    {
 
178
                        cout << "using byte sequences" << endl;
 
179
                        seqSize = ByteSeqSize;
 
180
                        break;
 
181
                    }
 
182
 
 
183
                    case '2':
 
184
                    {
 
185
                        cout << "using string sequences" << endl;
 
186
                        seqSize = StringSeqSize;
 
187
                        break;
 
188
                    }
 
189
 
 
190
                    case '3':
 
191
                    {
 
192
                        cout << "using variable-length struct sequences" << endl;
 
193
                        seqSize = StringDoubleSeqSize;
 
194
                        break;
 
195
                    }
 
196
 
 
197
                    case '4':
 
198
                    {
 
199
                        cout << "using fixed-length struct sequences" << endl;
 
200
                        seqSize = FixedSeqSize;
 
201
                        break;
 
202
                    }
 
203
                }
 
204
            }
 
205
            else if(c == 'e')
 
206
            {
 
207
                cout << "sending and receiving";
 
208
 
 
209
                cout << ' ' << repetitions;
 
210
                switch(currentType)
 
211
                {
 
212
                    case '1':
 
213
                    {
 
214
                        cout << " byte";
 
215
                        break;
 
216
                    }
 
217
 
 
218
                    case '2':
 
219
                    {
 
220
                        cout << " string";
 
221
                        break;
 
222
                    }
 
223
 
 
224
                    case '3':
 
225
                    {
 
226
                        cout << " variable-length struct";
 
227
                        break;
 
228
                    }
 
229
 
 
230
                    case '4':
 
231
                    {
 
232
                        cout << " fixed-length struct";
 
233
                        break;
 
234
                    }
 
235
                }
 
236
                cout << " sequences of size " << seqSize;
 
237
 
 
238
                cout << "..." << endl;
 
239
                
 
240
                list<Ice::AsyncResultPtr> results;
 
241
                for(int i = 0; i < repetitions; ++i)
 
242
                {
 
243
                    // Start the AMI request.
 
244
                    Ice::AsyncResultPtr r;
 
245
                    switch(currentType)
 
246
                    {
 
247
                    case '1':
 
248
                        r = throughput->begin_echoByteSeq(byteArr, byteSeqCB);
 
249
                        break;
 
250
 
 
251
                    case '2':
 
252
                        r = throughput->begin_echoStringSeq(stringSeq, stringSeqCB);
 
253
                        break;
 
254
 
 
255
                    case '3':
 
256
                        r = throughput->begin_echoStructSeq(structSeq, structSeqCB);
 
257
                        break;
 
258
 
 
259
                    case '4':
 
260
                        r = throughput->begin_echoFixedSeq(fixedSeq, fixedSeqCB);
 
261
                        break;
 
262
                    }
 
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.
 
267
                    r->waitForSent();
 
268
                    results.push_back(r);
 
269
 
 
270
                    // Remove any completed requests from the list of
 
271
                    // pending results.
 
272
                    list<Ice::AsyncResultPtr>::iterator p = results.begin();
 
273
                    while(p != results.end())
 
274
                    {
 
275
                        if((*p)->isCompleted())
 
276
                        {
 
277
                            p = results.erase(p);
 
278
                        }
 
279
                        else
 
280
                        {
 
281
                            ++p;
 
282
                        }
 
283
                    }
 
284
 
 
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)
 
290
                    {
 
291
                        r = results.front();
 
292
                        results.pop_front();
 
293
                        r->waitForCompleted();
 
294
                    }
 
295
                }
 
296
                // Before we're complete we must wait for all
 
297
                // responses to be received.
 
298
                while(!results.empty())
 
299
                {
 
300
                    Ice::AsyncResultPtr r = results.front();
 
301
                    results.pop_front();
 
302
                    r->waitForCompleted();
 
303
                }
 
304
 
 
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;
 
308
                int wireSize = 0;
 
309
                switch(currentType)
 
310
                {
 
311
                    case '1':
 
312
                    {
 
313
                        wireSize = 1;
 
314
                        break;
 
315
                    }
 
316
                    case '2':
 
317
                    {
 
318
                        wireSize = static_cast<int>(stringSeq[0].size());
 
319
                        break;
 
320
                    }
 
321
                    case '3':
 
322
                    {
 
323
                        wireSize = static_cast<int>(structSeq[0].s.size());
 
324
                        wireSize += 8; // Size of double on the wire.
 
325
                        break;
 
326
                    }
 
327
                    case '4':
 
328
                    {
 
329
                        wireSize = 16; // Size of two ints and a double on the wire.
 
330
                        break;
 
331
                    }
 
332
                }
 
333
                double mbit = repetitions * seqSize * wireSize * 8.0 / tm.toMicroSeconds();
 
334
                if(c == 'e')
 
335
                {
 
336
                    mbit *= 2;
 
337
                }
 
338
                cout << "throughput: " << setprecision(5) << mbit << "Mbps" << endl;
 
339
            }
 
340
            else if(c == 's')
 
341
            {
 
342
                throughput->shutdown();
 
343
            }
 
344
            else if(c == 'x')
 
345
            {
 
346
                // Nothing to do
 
347
            }
 
348
            else if(c == '?')
 
349
            {
 
350
                menu();
 
351
            }
 
352
            else
 
353
            {
 
354
                cout << "unknown command `" << c << "'" << endl;
 
355
                menu();
 
356
            }
 
357
        }
 
358
        catch(const Ice::Exception& ex)
 
359
        {
 
360
            cerr << ex << endl;
 
361
        }
 
362
    }
 
363
    while(cin.good() && c != 'x');
 
364
 
 
365
    return EXIT_SUCCESS;
 
366
}
 
367
 
 
368
void
 
369
ThroughputClient::menu()
 
370
{
 
371
    cout <<
 
372
        "usage:\n"
 
373
        "\n"
 
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"
 
380
        "\n"
 
381
        "select test to run:\n"
 
382
        "e: Echo (send and receive) sequence\n"
 
383
        "\n"
 
384
        "other commands:\n"
 
385
        "s: shutdown server\n"
 
386
        "x: exit\n"
 
387
        "?: help\n";
 
388
}