Remove dynamic exceptions
[anna.git] / source / comm / Service.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <anna/core/tracing/TraceMethod.hpp>
10 #include <anna/core/tracing/Logger.hpp>
11
12 #include <anna/xml/Node.hpp>
13
14 #include <anna/comm/Service.hpp>
15 #include <anna/comm/Server.hpp>
16
17 using namespace std;
18 using namespace anna;
19
20 void comm::Service::attach(comm::Server* server)
21 noexcept(false) {
22   LOGMETHOD(TraceMethod tm(Logger::Local7, "comm::Service", "attach", ANNA_FILE_LOCATION));
23   comm::Delivery::add(server);
24   server->attach(this);
25 }
26
27 //----------------------------------------------------------------------------------
28 // (1) Cuando no queda ningun recurso disponible se devuelve una excepcion
29 //----------------------------------------------------------------------------------
30 comm::Server* comm::Service::send(comm::Message& message)
31 noexcept(false) {
32   LOGMETHOD(TraceMethod tm(Logger::Local7, "comm::Service", "send", ANNA_FILE_LOCATION));
33   comm::Server* tryServer = NULL;
34   comm::Server* init = NULL;
35   bool stop = false;
36   bool sent = false;
37
38   while(stop == false) {
39     tryServer = static_cast <Server*>(Delivery::apply());                 // (1)
40
41     try {
42       if(init == NULL)
43         init = tryServer;
44       else if(init == tryServer)
45         stop = true;
46
47       tryServer->send(message);
48       sent = true;
49       break;
50     } catch(RuntimeException& ex) {
51       ex.trace();
52       stop = Delivery::fault(tryServer);
53     }
54   }
55
56   if(sent == false) {
57     string msg(asString());
58     msg += " | Service unavailable";
59     throw RuntimeException(msg, ANNA_FILE_LOCATION);
60   }
61
62   return tryServer;
63 }
64
65 comm::Server* comm::Service::send(comm::Message* message)
66 noexcept(false) {
67   if(message == NULL)
68     throw RuntimeException("comm::Service::send | Cannot send a NULL message", ANNA_FILE_LOCATION);
69
70   return (send(*message));
71 }
72
73 int comm::Service::broadcast(comm::Message& message)
74 {
75   using namespace anna::comm;
76   int result = 0;
77
78   for(iterator ii = begin(), maxii = end(); ii != maxii; ii ++) {
79     try {
80       server(ii)->send(message);
81       result ++;
82     } catch(RuntimeException& ex) {
83       ex.trace();
84     }
85   }
86
87   LOGDEBUG(
88     string msg("comm::Service::broadcast | ");
89     msg += asString();
90     msg += functions::asText(" | Sents number: ", result);
91     Logger::debug(msg, ANNA_FILE_LOCATION);
92   );
93   return result;
94 }
95
96 int comm::Service::broadcast(comm::Message* message)
97 {
98   if(message == NULL) {
99     Logger::write(Logger::Error, "comm::Service::broadcast | Cannot broadcast a NULL message", ANNA_FILE_LOCATION);
100     return 0;
101   }
102
103   return broadcast(*message);
104 }
105
106 string comm::Service::asString() const
107 {
108   string result("comm::Service { ");
109   result += Delivery::asString();
110   result += " | Critical: ";
111   result += functions::asString(a_isCritical);
112   return result += " }";
113 }
114
115 xml::Node* comm::Service::asXML(xml::Node* parent) const
116 {
117   xml::Node* service = parent->createChild("comm.Service");
118   Delivery::asXML(service);
119   service->createAttribute("Critical", functions::asString(a_isCritical));
120   return service;
121 }
122
123 /*static*/
124 comm::Server* comm::Service::server(comm::Delivery::iterator& ii)
125 {
126   return static_cast <Server*>(Delivery::resource(ii));
127 }
128
129 /*static*/
130 const comm::Server* comm::Service::server(comm::Delivery::const_iterator& ii)
131 {
132   return static_cast <const Server*>(Delivery::resource(ii));
133 }
134