bug in RC
[anna.git] / include / anna / comm / Delivery.hpp
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 #ifndef anna_comm_Delivery_hpp
10 #define anna_comm_Delivery_hpp
11
12 #include <vector>
13
14 #include <anna/core/mt/Mutex.hpp>
15 #include <anna/config/defines.hpp>
16
17 namespace anna {
18
19 namespace xml {
20 class Node;
21 }
22
23 namespace comm {
24
25 class Cluster;
26 class Resource;
27
28 /**
29    Clase que modela un algoritmo de reparto de carga.
30 */
31 class Delivery  : public Mutex {
32 public:
33   typedef std::vector <Resource*> Resources;
34   typedef Resources::iterator iterator;
35   typedef Resources::const_iterator const_iterator;
36
37   /*
38    * Establece el periodo de comprobacion de recuperacion de los
39    * recursos en los que se han detectado problemas internos.
40    */
41   static const Millisecond DefaultRecoveryTime;
42
43   /**
44      Destructor.
45   */
46   virtual ~Delivery() { a_resources.clear(); }
47
48   /**
49      Devuelve el nombre del reparto. Coincide con el indicado en el constructor.
50      \return el nombre del reparto. Coincide con el indicado en el constructor.
51   */
52   const std::string& getName() const throw() { return a_name; }
53
54   /**
55      Inicializa el reparto de recursos.
56   */
57   void initialize() throw(RuntimeException);
58
59   /**
60      Devuelve el estado anterior que tenia esta instancia. El resultado de #isAvailable
61      puede ser distinto a este metodo ya que a diferencia de este se basa en el estado
62      actual de los procesos asociados a este servicio, mientras que este metodo devuelve
63      el estado en el que estaban la ultima vez que se hizo una comprobacion.
64   */
65   bool wasAvailable() const throw() { return a_isAvailable; }
66
67   /*
68    * Obtiene el periodo de comprobacion de recuperacion de los recusos que han sido
69    * desactivados debido a que se han detectado problemas internos.
70    *
71    * \return El periodo de comprobacion de recuperacion
72    */
73   const Millisecond &getRecoveryTime() const throw() { return a_recoveryTime; }
74
75   /**
76    * Establece el periodo de comprobacion de recuperacion de los recusos que han sido
77    * desactivados debido a que se han detectado problemas internos.
78    *
79    * \param recoveryTime Periodo de comprobacion de recuperacion.
80    */
81   void setRecoveryTime(const Millisecond &recoveryTime) throw() { a_recoveryTime = recoveryTime; }
82
83   /**
84      Comprueba la lista de recursos remotos para comprobar si hay alguno que este disponible
85      (ver Resource::isAvailable) y no este deshabilitado (ver Resource::disable).
86
87      \return \em true si tiene algun recurso remoto utilizado o \em false en otro caso.
88   */
89   virtual bool isAvailable() const throw();
90
91   /**
92      Devuelve la instancia del recurso remoto que debemos usar en esta ocasion.
93      @return La instancia del recurso remoto que debemos usar en esta ocasion.
94      \warning Antes de invocar a este método la instancia se debe proteger de accesos concurrentes
95   */
96   Resource* apply() throw(RuntimeException);
97
98   /**
99      Este metodo sirve a nuestra aplicacion para notificar que el recurso ha dejado de
100      estar disponible.
101      \param resource Recurso remoto en el que hemos detectado el error.
102      \return \em true si ninguno de los recursos asociados a este reparto de carga estan disponibles o \em false en otro caso.
103      \warning Antes de invocar a este método la instancia se debe proteger de accesos concurrentes
104   */
105   bool fault(const Resource* resource) throw();
106
107   /**
108      Este metodo sirve a nuestra aplicacion para que el recurso vuelve a estar disponible.
109      \param resource Recurso remoto que hemos recuperado.
110      \return \em true si alguno de los recursos asociados a este reparto de carga pasa a estar disponible o \em false en otro caso.
111      \warning Antes de invocar a este método la instancia se debe proteger de accesos concurrentes
112   */
113   bool recover(const Resource* resource) throw();
114
115   /**
116      Indica si reparto contiene la referencia a un determinado recurso.
117      \return \em true si contiene la referencia al recurso recibido como parametro o \em false
118      en otro caso.
119   */
120   bool contains(const Resource* resource) const throw();
121
122   /**
123      Devuelve un iterador al comienzo de la lista de recursos remotos asociados a este reparto.
124      \return Un iterador al comienzo de la lista de recursos remotos asociados a este reparto.
125   */
126   iterator begin() throw() { return a_resources.begin(); }
127
128   /**
129      Devuelve un iterador al comienzo de la lista de recursos remotos asociados a este reparto.
130      \return Un iterador al comienzo de la lista de recursos remotos asociados a este reparto.
131   */
132   const_iterator begin() const throw() { return a_resources.begin(); }
133
134   /**
135      Devuelve un iterador al final de la lista de recursos remotos asociados a este reparto.
136      \return Un iterador al final de la lista de recursos remotos asociados a este reparto.
137   */
138   iterator end() throw() { return a_resources.end(); }
139
140   /**
141      Devuelve el numero de recursos asociados a la lista.
142      \return El numero de recursos asociados a la lista.
143   */
144   int size() const throw() { return a_resources.size(); }
145
146   /**
147      Devuelve un iterador al final de la lista de recursos remotos asociados a este reparto.
148      \return Un iterador al final de la lista de recursos remotos asociados a este reparto.
149   */
150   const_iterator end() const throw() { return a_resources.end(); }
151
152   /**
153      Devuelve una cadena con la informacion referente a este objeto.
154      @return Una cadena con la informacion referente a este objeto.
155   */
156   virtual std::string asString() const throw();
157
158   /**
159      Devuelve un nodo XML con la informacion referente a este objeto.
160      \param parent Nodo XML a partir del cual introducir la informacion.
161      \return Un nodo XML con la informacion referente a este objeto.
162   */
163   virtual xml::Node* asXML(xml::Node* parent) const throw();
164
165   /**
166      Devuelve el recurso remoto apuntado por el iterador recibido como parametro.
167      \param ii Iterador usado para recorrer los recursos asociados a este reparto.
168      \return El recurso remoto apuntado por el iterador recibido como parametro.
169   */
170   static Resource* resource(iterator& ii) throw() { return *ii; }
171
172   /**
173      Devuelve el recurso remoto apuntado por el iterador recibido como parametro.
174      \param ii Iterador usado para recorrer los recursos asociados a este reparto.
175      \return El recurso remoto apuntado por el iterador recibido como parametro.
176   */
177   static const Resource* resource(const_iterator& ii) throw() { return *ii; }
178
179 protected:
180   /**
181      Constructor.
182      @param name Nombre logico de este reparto.
183   */
184   Delivery(const char* name) :
185     a_name(name),
186     a_isAvailable(true),
187     a_recoveryTime(DefaultRecoveryTime),
188     a_timeStamp(0) {;}
189
190   /**
191      Conecta el recurso remoto recibido como parametro con este reparto.
192      @param resource Instancia del recurso que vamos a registrar en este reparto.
193   */
194   void add(Resource* resource) throw(RuntimeException);
195
196   /**
197      Inicializa el reparto de recursos.
198   */
199   virtual void do_initialize() throw(RuntimeException) = 0;
200
201   /**
202      Devuelve la instancia del recurso remoto que debemos que debemos usar en esta ocasion.
203      @return La instancia del recurso remoto que debemos usar en esta ocasion.
204   */
205   virtual Resource* do_apply() throw(RuntimeException) = 0;
206
207   /**
208      Este metodo sirve a nuestra aplicacion para indicar que no fue posible usar el
209      recurso obtenido mediante #apply.
210      \param resource Recurso remoto que ha ocasionado el error.
211      \return \em true si ninguno de los recursos asociados a este reparto de carga estan disponibles o \em false en otro caso.
212   */
213   virtual bool do_fault(const Resource* resource) throw();
214
215   /**
216      Este metodo sirve a nuestra aplicacion para indicar que ha recuperado la conexion
217      con el recurso.
218      \param resource Recurso remoto con el que ha recuperado la conexion.
219   */
220   virtual bool do_recover(const Resource* resource) throw();
221
222   /**
223      Este metodo sirve a nuestra aplicacion para indicar que ha recuperado la conexion
224      con el recurso.
225      \param resource Recurso remoto con el que ha recuperado la conexion.
226   */
227   virtual bool do_contains(const Resource* resource) const throw();
228
229 private:
230   std::string a_name;
231   Resources a_resources;
232   bool a_isAvailable;
233   Millisecond a_timeStamp;
234   Millisecond a_recoveryTime;
235
236   bool unsafe_recover(const Resource* resource) throw();
237
238   static bool internalErrorDetected(const Resource* resource) throw();
239 };
240
241 }
242 }
243
244 #endif