Updated license
[anna.git] / include / anna / comm / Communicator.hpp
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 #ifndef anna_comm_Communicator_hpp
38 #define anna_comm_Communicator_hpp
39
40 #include <vector>
41
42 #include <anna/config/defines.hpp>
43 #include <anna/core/DataBlock.hpp>
44 #include <anna/core/util/Recycler.hpp>
45 #include <anna/core/util/SortedVector.hpp>
46
47 #include <anna/app/Component.hpp>
48
49 #include <anna/comm/INetAddress.hpp>
50 #include <anna/comm/Socket.hpp>
51 #include <anna/comm/Status.hpp>
52
53 #include <anna/comm/internal/ConnectionRecover.hpp>
54
55 #include <anna/core/util/Millisecond.hpp>
56
57 namespace anna {
58
59 // MT
60 class ThreadManager;
61
62 namespace xml {
63 class Node;
64 }
65
66 namespace comm {
67
68 class Application;
69 class Transport;
70 class Message;
71 class ServerSocket;
72 class ClientSocket;
73 class LocalConnection;
74 class RemoteConnection;
75 class DatagramSocket;
76 class INetAddress;
77 class Handler;
78 class Server;
79 class Service;
80 class BinderSocket;
81 class ConnectionRecover;
82
83 namespace handler {
84 class LocalConnection;
85 class RemoteConnection;
86 class ClientSocket;
87 }
88
89 // ST
90 class Poll;
91
92 /**
93    Clase que integra todos los elementos implicados en la recepcin y/o envio y tratamiento de mensajes
94    de red.
95
96    Los mensajes recibidos y/o enviados a la capa de transporte seran tratados por el protocolo asociado
97    al socket cliente. Normalmente todos los socket clientes asociados a un comunicador tendran asociado
98    un mismo tipo de protocolo. Ver Transport.
99
100    Normalmente, y una vez que recibimos un mensaje (ver #eventReceiveMessage) aplicaremos algun codec (ver @ref Codec)
101    para interpretar el contenido del mensaje, de forma analoga, para enviar un mensaje a la capa de transporte
102    usando cualquier protocolo lo normal sera haber codificado cierta informacion usando algun codec.
103
104    \warning Siempre que usemos un Communicator debemos establecer una clase Application heredada
105    de comm::Application.
106 */
107 class Communicator : public app::Component {
108   struct SortByFileDescriptor {
109     static int value(const Handler*) throw();
110   };
111
112   /**
113    * Tamaño del búfer usado para leer los mensajes de la red.
114    * Se puede establecer desde comm::Communicator::setReceivingChunkSize.
115    */
116   static Millisecond st_ReceivingChunkSize;
117
118 public:
119   /**
120    * Modo de aceptar peticiones en el caso de una arquitectura ST.
121    * \warning Solo tiene efecto en caso de generar la libreria en modo ST.
122    * \see Communicator
123    */
124   struct WorkMode {
125     enum _v {
126       /**
127        * Un único proceso atiende todas las peticiones, el reparto de atención implementado asegura que todos
128        * los clientes tendrán un tiempo de respuesta similar, el tratamiento de N peticiones que llegan simultáneamente
129        * se realiza de forma secuencial. Es el modo usado hasta ahora en modo ST. Tiene la ventaja de ser el método que
130        * origina código más simple y fácil de mantener.
131        */
132       Single,
133       /**
134        *  Cada cliente tiene su propia copia del servidor original que trata sus peticiones de forma particular.
135        * De esta forma se podrían llegar a servir simultáneamente cada una de las peticiones de cada uno de los
136        * clientes conectados al servidor. Puede ser una buena opción si tenemos en cuenta la relación entre el
137        * rendimiento y la complejidad de desarrollo.
138        *
139        * Podria ser la mejor opcion para implementar un servidor de base de datos.
140        *
141        * \warning Solo puede usarse para implementar servidores finales, es decir, procesos que no requieran de la
142        * respuesta de ningun otro proceso remoto para realizar su operacion.
143        */
144       Clone
145     };
146   };
147
148   /**
149    * Numero de mínimo milisegundos esperados para intentar la recuperacion de la conexion con los
150    * servidores en caso de detectar algun error.
151    */
152   static const Millisecond MinRecoveryTime;
153
154   /**
155      Numero de milisegundos esperados para intentar la recuperacion de la conexion con los
156      servidores en caso de detectar algun error.
157   */
158   static const Millisecond DefaultRecoveryTime;
159
160   /**
161    * Numero de mínimo milisegundos esperados para intentar la recuperacion de la conexion con los
162    * servidores en caso de detectar algun error.
163    */
164   static const Millisecond MaxRecoveryTime;
165
166   /**
167    * Periodo de tiempo mínimo que estará intentando conectar con servidores cada vez que se cumpla el periodo de
168    * comprobación de conexiones.
169    */
170   static const Millisecond MinTryingConnectionTime;
171
172   /**
173    * Periodo de tiempo usado por defectoque estará intentando conectar con servidores cada vez que se cumpla el
174    * periodo de comprobación de conexiones.
175    */
176   static const Millisecond DefaultTryingConnectionTime;
177
178   /**
179    * Periodo de tiempo máximo que estará intentando conectar con servidores cada vez que se cumpla el periodo de
180    * comprobación de conexiones.
181    */
182   static const Millisecond MaxTryingConnectionTime;
183
184   /**
185    * Tamaño mínimo de la cola de entrada de mensajes que se puede establecer.
186    */
187   static const int MinReceivingChunkSize = 2 * 1024;
188
189   /**
190    * Tamaño máximo de la cola de entrada de mensajes que se puede establecer.
191    */
192   static const int MaxReceivingChunkSize = 64 * 1024;
193
194   /**
195      Numero de milisegundos esperados para considerar que un cliente remoto ha abandonado
196      la conexion.
197   */
198   static const Millisecond DefaultTimeout;
199
200   /**
201    * Tamaño máximo del búfer a tratar de forma ininterrumpida.
202    */
203   static const int DefaultChunkSize = 16 * 1024;
204
205   typedef SortedVector <Handler, SortByFileDescriptor> Handlers; /**< Definicion para gestionar los controladores asociados a este comunicador */
206   typedef Handlers::const_iterator const_handler_iterator; /**< Definicion para el iterador de controladores */
207   typedef Handlers::iterator handler_iterator; /**< Definicion para el iterador de controladores */
208
209   typedef std::vector <const Service*> Services; /**< Definicion para gestionar los servicios asociados a este comunicador */
210   typedef Services::const_iterator const_service_iterator; /**< Definicion para el iterador de servicios */
211
212   /**
213      Constructor.
214      \param acceptMode Modo en que se trata las peticiones.
215   */
216   Communicator(const WorkMode::_v acceptMode = WorkMode::Single);
217
218   /**
219    * Destructor
220    */
221   virtual ~Communicator();
222
223   /**
224      Devuelve el numero de segundos esperado para intentar recuperar las conexiones de los servidores
225      con los que se han detectado errores de conexion.
226      @return El numero de segundos esperado para intentar recuperar las conexiones de los servidores
227      con los que se han detectado errores de conexion.
228   */
229   const Millisecond &getRecoveryTime() const throw() { return a_recoveryTime; }
230
231   /**
232      Devuelve el estado de este proceso con respecto al sistema de comunicaciones.
233      \return El estado de este proceso con respecto al sistema de comunicaciones.
234   */
235   const Status& getStatus() const throw() { return a_status; }
236
237   /**
238      Devuelve el numero de milisegundos maximo que puede estar un manejador de conexion local
239      sin recibir mensajes antes de ser cerrado por el nucleo.
240      \return el numero de milisegundos maximo que puede estar un manejador de conexion local
241      sin recibir mensajes antes de ser cerrado por el nucleo.
242   */
243   const Millisecond &getTimeout() const throw() { return a_timeout; }
244
245   /**
246    * Devuelve el modo de tratamiento de conexiones establecido en el constructor.
247    */
248   WorkMode::_v getWorkMode() const throw() { return a_workMode; }
249
250   /**
251      Devuelve \em true si este comunicador esta atendiendo peticiones como servidor o \em false en otro
252      caso.
253      @return \em true si este comunicador esta atendiendo peticiones como servidor o \em false en otro
254      caso.
255   */
256   bool isServing() const throw() { return a_isServing; }
257
258   /**
259      Devuelve el estado del indicador de peticion de parada.
260      \return el estado del indicador de peticion de parada.
261   */
262   bool hasRequestedStop() const throw() { return a_requestedStop; }
263
264   /**
265    * Informa al comunicador de que hay algún socket que ha solicitado el cierre de la conexión.
266    */
267   void notifyPendingClose() throw() { a_pendingClose = true; }
268
269   /**
270      Establece el numero de milisegundos esperado para intentar recuperar las conexiones de los servidores
271      con los que se han detectado errores de conexion.
272
273      @param recoveryTime numero de milisegundos esperado para intentar recuperar las conexiones de los
274      servidores con los que se han detectado errores de conexion.
275
276      \warning el valor indicado deberá estar entre #MinRecoveryTime y #MaxRecoveryTime
277   */
278   void setRecoveryTime(const Millisecond &recoveryTime) throw(RuntimeException);
279
280   /**
281      Establece el numero de milisegundos empleados en intentar conectar con los servidores caídos cada
282      vez que se cumple el periodo de recuperación y hay servidores caídos.
283
284      @param tryingConnectionTime numero de milisegundos empleados en intentar recuperar las conexiones
285      de los servidores con los que se han detectado errores de conexion.
286
287      \warning el valor indicado deberá estar entre #MinTryingConnectionTime y #MaxTryingConnectionTime
288   */
289   void setTryingConnectionTime(const Millisecond &tryingConnectionTime) throw(RuntimeException);
290
291   /**
292    * Devuelve el numero de milisegundos empleados en intentar conectar con los servidores caídos.
293    */
294   const Millisecond &getTryingConnectionTime() const throw() { return a_tryingConnectionTime; }
295
296   /**
297    * Establece el tamaño del bloque de memoria usado para procesar los mensajes entrantes. Todos
298    * los mensajes completos contenidos en el chunk se procesarán de forma ininterrumpida.
299    * \param receivingChunkSize Número de bytes a leer/procesar de forma ininterrumpida.
300    *
301    * \warning el valor indicado deberá estar entre #MinReceivingChunkSize y #MaxReceivingChunkSize
302    * \warning Experimentalmente se ha comprobado que los mejores rendimientos se obtiene cuando
303    * este valor y el MaxPendingBytes del control de congestión tiene valores cercanos, así que
304    * cuando se cambia este valor también se invocará a CongestionController::setMaxPendingBytes para
305    * establecer este mismo valor.
306    */
307   static void setReceivingChunkSize(const int receivingChunkSize) throw(RuntimeException);
308
309   /**
310    * Obtiene el tamaño máximo del bloque de memoria a procesar de forma ininterrumpida.
311    * \return el tamaño máximo del bloque de memoria a procesar de forma ininterrumpida.
312    */
313   static int getReceivingChunkSize() throw() { return st_ReceivingChunkSize; }
314
315   /**
316      Establece el numero de milisegundos maximo que puede estar un manejador de conexion local
317      sin recibir mensajes antes de ser cerrado por el nucleo.
318      \param timeout Numero de milisegundos maximo sin recibir mensajes.
319   */
320   void setTimeout(const Millisecond & timeout) throw() { a_timeout = timeout; }
321
322   /**
323    * Establece el nivel de congestión global a partir del cual un servidor no aceptará nuevas conexiones. Su valor
324    * por defecto será comm::CongestionController::MaxLevel.
325    *
326    * \param levelOfDenialService Nivel de congestión global a partir del cual no se permitirán nuevas conexiones.
327    *
328    * \warning Debe estar entre [comm::CongestionController::MaxLevel - 2, comm::CongestionController::MaxLevel].
329    */
330   void setLevelOfDenialService(const int levelOfDenialService) throw(RuntimeException);
331
332   /**
333    * Devuelve el nivel de congestión a partir del cual un servidor no aceptará nuevas conexiones.
334    * \return el nivel de congestión a partir del cual un servidor no aceptará nuevas conexiones.
335    */
336   int getLevelOfDenialService() const throw() { return a_levelOfDenialService; }
337
338   /**
339      Registra un servidor de socket a la lista de peticiones por las que atiende peticiones este
340      Communicator. Un Communicator puede atender peticiones por un numero indeterminado de direcciones
341      lo que nos permite disear facilmente sistemas tolerantes a fallos.
342
343      \param serverSocket Servidor de socket por el que vamos a atender el establecimiento de conexiones
344      una vez que invoquemos al Metodo #accept.
345   */
346   void attach(ServerSocket* serverSocket) throw(RuntimeException);
347
348   /**
349      Registra una conexion Local entre alguno de los ServerSocket definidos en nuestra aplicacion
350      y algun cliente remoto que solicita la conexion.
351
352      Antes de pasar a gestionar esta conexion debera de haber sido acceptada en el metodo
353      #eventAcceptConnection (a no ser que re-escribamos su comportamiento aceptara conexiones
354      de cualquier cliente).
355
356      \param localConnection Instancia de la conexion local que vamos a controlar.
357
358      \warning Exclusivamente uso interno
359   */
360   void attach(LocalConnection* localConnection) throw(RuntimeException);
361
362   /**
363      Establece la conexion entre el comunicador y un ClientSocket recibido como parametro.
364      El socket recibido se inicializa se fuera necesario.
365
366      \param clientSocket Instancia del socket que vamos a controlar.
367   */
368   void attach(ClientSocket* clientSocket) throw(RuntimeException);
369
370   /**
371      Establece la conexion entre el comunicador y un DatagramSocket recibido como parametro.
372      El socket recibido se inicializa se fuera necesario.
373
374      \param datagramSocket Instancia del socket que vamos a controlar.
375   */
376   void attach(DatagramSocket* datagramSocket) throw(RuntimeException);
377
378   /**
379      Conecta un conector externo a este comunicador.
380      \param handler Controlador de comunicaciones externas.
381      \warning Debe de haber sido creado como de tipo Handler::Type::Custom.
382   */
383   void attach(Handler* handler) throw(RuntimeException);
384
385   /**
386      Conecta un servicio de reparto de comunicaciones con este comunicador. El estado de
387      disponibilidad/indisponibilidad de este comunicador estara definido en base a la
388      disponibilidad de todos los servicios definidos como criticos.
389      \param service Instancia del servicio.
390      \warning Todos los servicios registrados como criticos deberian estar asociados al comunicador.
391   */
392   void attach(Service* service) throw(RuntimeException);
393
394   /**
395      Desconecta el ServerSocket que fue previamente conectado con #attach
396      \param serverSocket Instancia del socket que vamos a desconectar.
397      \warning Este metodo es invocado automaticamente desde el nucleo de anna.comm y no deberia
398      ser usado por el programador final.
399   */
400   void detach(ServerSocket* serverSocket) throw();
401
402   /**
403      Desconecta el ClientSocket que fue previamente conectado con #attach
404      \param clientSocket Instancia del socket que vamos a desconectar.
405      \warning Este metodo es invocado automaticamente desde el nucleo de ANNA.comm y no deberia
406      ser usado por el programador final.
407   */
408   void detach(ClientSocket* clientSocket) throw();
409
410   /**
411      Desconecta el conector externo de este comunicador. Supone que todas las operaciones
412      adicionales necesarias para liberar los recursos de este fichero seran realizadas
413      externamente.
414
415      \param handler Controlador de comunicaciones externas.
416
417      \warning Exclusivamente uso interno
418   */
419   void detach(Handler* handler) throw();
420
421   /**
422      Devuelve el manejador asociado al ClientSocket recibido como parametro.
423      \param clientSocket Socket cliente del que queremos obtener en handler.
424      \return El manejador asociado al socket recibido como parametro. Puede ser NULL.
425   */
426   const Handler* getHandler(const ClientSocket& clientSocket) throw(RuntimeException);
427
428   /**
429       El thread que invoca a este Metodo entra en un proceso continuo de comprobacin/recepcin
430       de mensajes, todos los eventos que pueden afectar al comportamiento de nuestro comunicador como son
431       aceptacin y cierre de conexiones, caidas, recepcin de mensajes, etc, etc se notifican a
432       traves de los Metodos manejadores de eventos de esta misma clase.
433       El thread saldra de este bucle tras la invocacion del Metodo #requestStop.
434    */
435   void accept() throw(RuntimeException);
436
437   /**
438      Solicita la parada de este comunicador.
439   */
440   void requestStop() throw();
441
442   /**
443      Devuelve \em true si el ClientSocket recibido como parametro sigue siendo valido o \em false
444      en caso de que haya dejado de ser valido debido al cierre del extremo remoto, por ejemplo.
445
446      Si el ClientSocket recibido es NULL siempre devolvera \em false.
447
448      \return \em true si el ClientSocket recibido como parametro sigue siendo valido o \em false
449      en caso de que haya dejado de ser valido debido al cierre del extremo remoto, por ejemplo.
450   */
451   bool isUsable(const ClientSocket* clientSocket) throw();
452
453   /**
454      Devuelve el numero handlers activos.
455      \return el numero handlers activos.
456   */
457   int handler_size() const throw() { return a_handlers.size(); }
458
459   /**
460      Devuelve un iterador que apunta el primer controlador.
461      \return un iterador que apunta el primer controlador.
462   */
463   handler_iterator handler_begin() throw() { return a_handlers.begin(); }
464
465   /**
466      Devuelve un iterador que apunta al final de la lista de controladores.
467      \return un iterador que apunta al final de la lista de controladores.
468   */
469   handler_iterator handler_end() throw() { return a_handlers.end(); }
470
471   /**
472      Devuelve un iterador que apunta el primer controlador.
473      \return un iterador que apunta el primer controlador.
474   */
475   const_handler_iterator handler_begin() const throw() { return a_handlers.begin(); }
476
477   /**
478      Devuelve un iterador que apunta al final de la lista de controladores.
479      \return un iterador que apunta al final de la lista de controladores.
480   */
481   const_handler_iterator handler_end() const throw() { return a_handlers.end(); }
482
483   /**
484      Devuelve un iterador que apunta el primer servicio.
485      \return un iterador que apunta el primer service.
486   */
487   const_service_iterator service_begin() const throw() { return a_services.begin(); }
488
489   /**
490      Devuelve un iterador que apunta al final de la lista de servicios.
491      \return un iterador que apunta al final de la lista de servicios.
492   */
493   const_service_iterator service_end() const throw() { return a_services.end(); }
494
495   /**
496      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador ante
497      un evento generado por el propio programador.
498
499      Sera invocado por algun Metodo del programador con el objetivo de actuar sobre su comunicador
500      en una situacin indeterminada.
501
502      La interpretacin del identificador y el contenido de este contexto sera problema exclusivo
503      del programador ya que ANNA.comm no impone ninguna regla ni realiza ningn tipo de proceso
504      adicional con estos datos.
505
506      @param id Identifica el evento generado.
507      @param context Contexto asociado al evento que ha generado el usuario.
508
509      \warning Este Metodo no debera generar ningn tipo de excepcin.
510   */
511   virtual void eventUser(const char* id, const void* context) throw() {;}
512
513   /**
514      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
515      el nucleo de ANNA.comm notifica la perdida de conexion con la direccion IP indicada.
516
517      \param address Interfaz de red que ha dejado de estar disponible.
518
519      \warning
520      \li La forma en que detectara la caida del interfaz de red no esta dentro del ambito
521      del problema de ANNA.comm debera haber una capa superior que se encargue de comprobar las
522      interfaces.
523      \li El nucleo de ANNA.comm necesita conocer este evento por lo que cualquier implementacin
524      debera invocar al Metodo eventBreakAddress de su clase base.
525   */
526   virtual void eventBreakAddress(const in_addr_t& address) throw();
527
528   /**
529      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
530      el nucleo de ANNA.comm notifica la recuperacin de conexion con la direccion IP indicada.
531
532      \param address Interfaz de red que ha vuelto a estar disponible.
533
534      \warning
535      \li La forma en que detectara la recuperacin del interfaz de red no esta dentro del ambito
536      del problema de ANNA.comm debera haber una capa superior que se encargue de comprobar las
537      interfaces.
538      \li El nucleo de ANNA.comm necesita conocer este evento por lo que cualquier implementacin
539      debera invocar al Metodo eventRecoverAddress de su clase base.
540   */
541   virtual void eventRecoverAddress(const in_addr_t& address) throw();
542
543   /**
544      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
545      el nucleo de ANNA.comm notifica que ha detectado una peticion de conexion desde un
546      proceso remoto a un ServerSocket asociado a este comunicador.
547      Cualquier re-implementacion de este metodo debe invocar al metodo de la clase base y
548      devolver \em false en caso de que este lo devuelva.
549
550      @param clientSocket Socket cliente que solicita acceso.
551
552      \return \em true si la conexion es acceptada a \em false en otro caso, en cuyo caso se liberaran
553      automaticamente todos los recursos asociados a la peticion de conexion.
554
555      \warning Desde ANNA.comm 1.11.18 se mide el nivel de carga del proceso y si se evalúa como
556      congestionado no permitirá aceptar la nueva conexión.
557   */
558   virtual bool eventAcceptConnection(const ClientSocket& clientSocket) throw(RuntimeException);
559
560   /**
561       Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
562       el nucleo de ANNA.comm notifica la creacion de una nueva conexion con el proceso servidor
563       recibido como parametro.
564
565       En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
566       todas las operaciones necesarias.
567
568       \warning Cualquier reimplementacion de este metodo debe comenzar invocando al metodo original de la
569       clase Communicator de la que herede nuestra clase.
570
571       @param server Proceso servidor con el que hemos establecido la conexion.
572
573       \see Host::createServer
574    */
575   virtual void eventCreateConnection(const Server* server) throw();
576
577   /**
578       Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
579       el nucleo de ANNA.comm notifica la creacion de una nueva conexion con el servicio de reparto
580       recibido como parametro.
581
582       En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
583       todas las operaciones necesarias.
584
585       \warning  Cualquier reimplementacion de este metodo debe comenzar invocando al metodo original de la
586       clase Communicator de la que herede nuestra clase.
587
588       @param service Servicio con el que hemos establecido la conexion.
589
590       \see Host::createServer
591    */
592   virtual void eventCreateConnection(const Service* service) throw();
593
594   /**
595      Establece las acciones a realizar cuando la clase Communicator detecta la llegada de un
596      mensaje completo analizado con el protocolo indicado.
597
598      Se invocara desde el Metodo #accept cuando se detecta la llegada de un mensaje.
599
600      En entorno MT todos los threads actuaran sobre la unica instancia del comm::Communicator
601      lo que restara eficacia debido al bajo nivel de paralelismo.
602
603      @param clientSocket Socket cliente por el que ha llegado el mensaje.
604      @param message Ultimo mensaje recibido. El bloque de datos recibido ya ha sido
605      decodificado aplicando las reglas establecidas por la capa de transporte asociado
606      al ClientSocket por el que llega el mensaje.
607
608      \warning Para ANNA.comm version 1.5.2 y posteriores se deberian usar el sistema de
609      receiveres (anna::comm::Receiver) que ofrece mayor rendimiento y facilita la programacion
610      en entorno MT.
611   */
612   virtual void eventReceiveMessage(ClientSocket& clientSocket, const Message& message)
613   throw(RuntimeException) { ; }
614
615   /**
616      Establece las acciones a realizar cuando el nucleo de ANNA.comm notifica que ha
617      cerrado un anna::comm::ClientSocket debido a un consumo excesivo de memoria.
618      \param clientSocket Socket cliente que va a ser cerrado por el nucleo de ANNA.comm.
619   */
620   virtual void eventOverQuota(const ClientSocket& clientSocket) throw() {;}
621
622   /**
623      Establece las acciones a realizar cuando el núcleo de ANNA.comm notifica que ha
624      cerrado un anna::comm::ClientSocket debido a que ha recibido un mensaje que no
625      ha sido analizado correctamente.
626      \param clientSocket Socket cliente que va a ser cerrado por el nucleo de ANNA.comm.
627   */
628   virtual void eventDiscardConnection(const ClientSocket& clientSocket) throw() {;}
629
630   /**
631    * Método manejador invocado cuando un client socket que tiene activado el indicador de ignorar los
632    * mensajes entrantes recibe un mensaje.
633    * \param clientSocket ClientSocket por el que se recibe el mensaje.
634    * \param burst Bloque de datos que contiene la trama recibida.
635    */
636   virtual void eventIgnoreBurst(const ClientSocket& clientSocket, const DataBlock& burst) throw() {;}
637
638   /**
639      Devuelve una cadena con la informacion mas relevante de esta instancia.
640      \return Una cadena con la informacion mas relevante de esta instancia.
641   */
642   std::string asString() const throw();
643
644   /**
645      Devuelve un documento XML con la informacion mas relevante de esta instancia.
646      \param parent Nodo XML del que colgar la informacion referente a esta instancia.
647      \return Un documento XML con la informacion mas relevante de esta instancia.
648   */
649   virtual xml::Node* asXML(xml::Node* parent) const throw();
650
651   /**
652      Devuelve el controlador apuntado por el iterador recibido.
653      \param ii Iterador con el que estamos recorriendo los controladores.
654      \return el controlador apuntado por el iterador recibido.
655   */
656   static Handler* handler(handler_iterator& ii) throw() { return Handlers::data(ii); }
657
658   /**
659      Devuelve el controlador apuntado por el iterador recibido.
660      \param ii Iterador con el que estamos recorriendo los controladores.
661      \return el controlador apuntado por el iterador recibido.
662   */
663   static const Handler* handler(const_handler_iterator& ii) throw() { return Handlers::data(ii); }
664
665   /**
666      Devuelve el servicio apuntado por el iterador recibido.
667      \param ii Iterador con el que estamos recorriendo los servicios.
668      \return el servicio apuntado por el iterador recibido.
669   */
670   static const Service* service(const_service_iterator& ii) throw() { return *ii; }
671
672   /**
673      Devuelve la cadena por la que podemos buscar el componente.
674      \return La cadena por la que podemos buscar el componente.
675      \see Application::find
676   */
677   static const char* getClassName() { return "anna::comm::Communicator"; }
678
679 protected:
680   /**
681      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
682      el nucleo de ANNA.comm notifica la perdida de conexion con un servidor remoto.
683
684      En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
685      todas las operaciones necesarias.
686
687      @param clientSocket Socket cliente asociado a esta rotura de conexion.
688
689      \warning despues de llamar a este Metodo el clientSocket pasado como parametro se liberara por lo
690      que despues de este Metodo esta instancia no debera utilizarse.
691      \warning Estado MT: \code [Tx] -> Communicator \endcode
692   */
693   virtual void eventBreakConnection(const ClientSocket& clientSocket) throw() {;}
694
695   /**
696      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
697      el nucleo de ANNA.comm notifica la perdida de conexion de una conexion generada por un server socket.
698
699      En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
700      todas las operaciones necesarias.
701
702      @param clientSocket Socket cliente asociado a esta rotura de conexion.
703   */
704   virtual void eventBreakLocalConnection(const ClientSocket& clientSocket) throw() {;}
705
706
707   /**
708      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
709      el nucleo de ANNA.comm notifica la perdida de conexion con el proceso servidor recibido como
710      parametro.
711
712      Se invocara desde #accept(ServerSocket&) cuando no se detecta la rotura de conexion con un
713      socket asociado a uno de nuestros servidores.
714
715      En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
716      todas las operaciones necesarias.
717
718      Las acciones realizadas por este metodo incluyen:
719      \li Cierre del socket asociado al proceso servidor cuya conexion ha caido.
720      \li Reorganizacion del sistema de reparto de carga para que marque el proceso servidor como no disponible.
721      \li Activar los sistemas de recuperacion de conexion en el caso de que el servidor que ha caido
722      vuelva a estar disponible.
723
724      \warning Cualquier reimplementacion de este metodo debe comenzar invocando al metodo original de la
725      clase Communicator de la que herede nuestra clase.
726      \warning Estado MT: \code [Tx] -> Communicator \endcode
727
728      @param server Proceso servidor con el que hemos perdido la conexion.
729   */
730   virtual void eventBreakConnection(const Server* server) throw();
731
732   /**
733      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador
734      cuando el nucleo de anna.comm notifica la perdida de conexion con todos los procesos
735      asociados al servicio recibido como parametro.
736
737      \param service Servicio que ha dejado de estar disponible.
738      \warning Estado MT: \code [Tx] -> Communicator \endcode
739   */
740   virtual void eventBreakConnection(const Service* service) throw();
741
742   /**
743      Establecer la configuracin de este comunicador. El cargador de configuracin se encarga de establecer
744      los ServerSocket por los que este comunicador va a atender peticiones y/o los procesos servidores
745      remotos con los que tenemos que establecer el canal de comunicaciones.
746
747      \warning Este Metodo debe invocarse desde las clases heredadas.
748   */
749   virtual void do_initialize() throw(RuntimeException) {;}
750
751   /**
752      Solicita la parada de este comunicador. Se reimplementa para mantener el interfaz de la clase
753      Component de la que hereda este Communicator.
754   */
755   void do_stop() throw() { requestStop(); }
756
757   /**
758      Establece el estado de este proceso con respecto al sistema de comunicaciones
759      @param status Estado del sistema de comunicaciones que deseamos establecer.
760   */
761   virtual void setStatus(const Status& status) throw();
762
763   /**
764      Establece la conexion entre el comunicador y un socket dedicado a la comparticion de una
765      determinada direccion IP:puerto.
766
767      \param binderSocket Define un socket por el que tratar las peticiones de comparticion
768      de una determinada direccion IP:puerto.
769
770      \internal
771   */
772   void attach(BinderSocket* binderSocket) throw(RuntimeException);
773
774   /**
775      Desconecta el BinderSocket que fue previamente conectado con attach(BinderSocket*).
776      \param binderSocket Instancia del BinderSocket a desconectar.
777      \warning Exclusivamente uso interno
778   */
779   void detach(BinderSocket* binderSocket) throw();
780
781   /**
782      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
783      el nucleo de ANNA.comm notifica que este comunicador esta preparado para comenzar a
784      aceptar y/o enviar mensajes.
785
786      Se invocara desde el metodo #accept inmediatamente antes de comenzar a
787      comprobar la llegada de mensajes.
788
789      En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
790      todas las operaciones necesarias.
791   */
792   virtual void eventStartup() throw(RuntimeException) {;}
793
794   /**
795      Metodo manejador de evento que permite ajustar el funcionamiento de nuestro comunicador cuando
796      el nucleo de ANNA.comm notifica que este va a dejar de atender peticiones.
797
798      En la mayoria de los casos no sera necesario indicar ninguna accion ya que ANNA.comm realiza
799      todas las operaciones necesarias.
800   */
801   virtual void eventShutdown() throw();
802
803 private:
804   const WorkMode::_v a_workMode;
805   bool a_isServing;
806   bool a_requestedStop;
807   Handlers a_handlers;
808   Millisecond a_recoveryTime;
809   Status a_status;
810   Services a_services;
811   Millisecond a_timeout;
812   comm::Handler* a_mainHandler;
813   ConnectionRecover* a_connectionRecover;
814   bool a_pendingClose;
815   Millisecond a_tryingConnectionTime;
816   int a_levelOfDenialService;
817
818   // ST
819   Poll* a_poll;
820   Handlers a_timedouts;
821   void singlethreadedAccept() throw(RuntimeException);
822
823   // MT
824   ThreadManager* a_threadManager;
825   void multithreadedAccept() throw(RuntimeException);
826
827   ConnectionRecover* getConnectionRecover() throw() { return a_connectionRecover; }
828
829   void attach(RemoteConnection* remoteConnection) throw(RuntimeException);
830
831   void insert(Handler*) throw(RuntimeException);
832   Handler* find(const int fd) throw() { return a_handlers.find(fd); }
833
834   // Reimplementado de app::Component
835   void do_cloneParent() throw(RuntimeException);
836   void do_cloneChild() throw();
837
838   friend class Handler;
839
840   friend class Server;
841   // attach (RemoteConnection)
842
843   friend class handler::RemoteConnection;
844   // getConnectionRecover, eventBreakConnection
845
846   friend class handler::ClientSocket;
847   // eventBreakConnection
848
849   // EDU
850   friend class handler::LocalConnection;
851   // eventBreakLocalConnection
852 };
853
854 }
855 }
856
857 #endif
858