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