Updated license
[anna.git] / source / test / Control.cpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #include <iostream>
38
39 #include <anna/core/mt/Guard.hpp>
40 #include <anna/core/functions.hpp>
41 #include <anna/core/tracing/Logger.hpp>
42 #include <anna/core/util/DelayMeter.hpp>
43 #include <anna/core/tracing/TraceMethod.hpp>
44
45 #include <anna/xml/Node.hpp>
46 #include <anna/xml/Attribute.hpp>
47
48 #include <anna/app/Application.hpp>
49
50 #include <anna/comm/Communicator.hpp>
51 #include <anna/comm/CongestionController.hpp>
52
53 #include <anna/test/Control.hpp>
54
55 using namespace std;
56 using namespace anna;
57
58 typedef Guard MyGuard;
59 //typedef Guard <test::Control> MyGuard;
60
61 test::Control::Control (comm::Communicator* engine) :
62    a_engine (*engine),
63    a_maxMessage (-1),
64    a_initTime (0),
65    a_avgDelay ("AvgDelay"),
66    a_avgLatency ("AvgLatency"),
67    a_delay (0)
68 {;}
69
70 bool test::Control::canContinue (const comm::socket::Client&)
71    throw (RuntimeException)
72 {
73    LOGMETHOD (TraceMethod ttmm (Logger::Local7, "test::Control::canContinue", ANNA_FILE_LOCATION));
74
75    comm::CongestionController& congestionController = comm::CongestionController::instantiate ();
76
77    if (a_maxMessage != -1 && congestionController.getMessageCounter () >= a_maxMessage) {
78       stop ();
79       return false;
80    }
81
82    MyGuard guard (this);
83
84    if (a_initTime == 0)
85       a_initTime = anna::Millisecond::getTime ();
86
87    return true;
88 }
89
90 void test::Control::delay ()
91    throw (RuntimeException)
92 {
93    LOGMETHOD (TraceMethod ttmm (Logger::Local7, "test::Control::delay", ANNA_FILE_LOCATION));
94
95   if (a_delay > 0) {
96       Millisecond random = Millisecond ((a_delay > 10) ? (rand () % (a_delay / 10)): 0);
97       Millisecond delay (a_delay);
98
99       int sign = rand () % 2;
100
101       if (sign == 0)
102          delay -= random;
103       else
104          delay += random;
105
106       DelayMeter <Microsecond> meter;
107
108       anna::functions::sleep (delay);
109
110       if (true) {
111          MyGuard guard (this);
112          a_avgDelay += meter.getValue();
113       }
114    }
115 }
116
117 // Aproximación del valor que lleva en mensaje en cola I/O
118 Millisecond test::Control::latency (const Millisecond& init)
119    throw (RuntimeException)
120 {
121    LOGMETHOD (TraceMethod ttmm (Logger::Local7, "test::Control::latency", ANNA_FILE_LOCATION));
122
123    const Millisecond now = anna::Millisecond::getTime();
124
125    const Millisecond _latency = now - init;
126
127    if (_latency > 0) {
128       MyGuard guard (this);
129       a_avgLatency += _latency;
130    }
131
132    return now;
133 }
134
135 void  test::Control::report ()
136    throw ()
137 {
138    const Millisecond serviceTime = anna::Millisecond::getTime () - a_initTime;
139
140    comm::CongestionController& congestionController = comm::CongestionController::instantiate ();
141
142    const int workload = (serviceTime == 0) ? 0: congestionController.getMessageCounter () * 1000 / serviceTime;
143    string msg (anna::functions::asText ("Time of service: ", (int) serviceTime));
144    msg += anna::functions::asText (" ms | Workload: ", workload);
145    msg += anna::functions::asText (" msg/sec | Received Messages: ", congestionController.getMessageCounter ());
146    msg += anna::functions::asText (" | Processed Messages: ", congestionController.getSuccessCounter ());
147    Logger::notice (msg, ANNA_FILE_LOCATION);
148    cout << msg << endl << endl;
149
150    msg = "Average delay (us): ";
151    msg += a_avgDelay.asString ();
152    Logger::notice (msg, ANNA_FILE_LOCATION);
153    cout << msg << endl << endl;
154
155    msg = "Average latency (ms): ";
156    msg += a_avgLatency.asString ();
157    Logger::notice (msg, ANNA_FILE_LOCATION);
158    cout << msg << endl << endl;
159 }
160
161 void test::Control::stop ()
162    throw (RuntimeException)
163 {
164    if (a_engine.hasRequestedStop () == true)
165       return;
166
167    a_engine.requestStop ();
168
169 }
170
171 xml::Node* test::Control::asXML (xml::Node* parent)
172    throw ()
173 {
174    xml::Node* result = parent->createChild ("test.Control");
175
176    result->createAttribute ("MaxMessage", a_maxMessage);
177    result->createAttribute ("AvgDelay", a_avgDelay.value ().asString());
178    result->createAttribute ("AvgLatency", a_avgLatency.value ().asString());
179
180    return result;
181 }
182