EC_ObserverStrategy.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 /**
00004  *  @file   EC_ObserverStrategy.h
00005  *
00006  *  EC_ObserverStrategy.h,v 1.37 2006/03/15 07:52:22 jtc Exp
00007  *
00008  *  @author Carlos O'Ryan (coryan@cs.wustl.edu)
00009  *  @author Johnny Willemsen (jwillemsen@remedy.nl)
00010  *  @author Kees van Marle (kvmarle@remedy.nl)
00011  *
00012  * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and
00013  * other members of the DOC group. More details can be found in:
00014  *
00015  * http://doc.ece.uci.edu/~coryan/EC/index.html
00016  */
00017 
00018 #ifndef TAO_EC_OBSERVERSTRATEGY_H
00019 #define TAO_EC_OBSERVERSTRATEGY_H
00020 
00021 #include /**/ "ace/pre.h"
00022 
00023 #include "orbsvcs/ESF/ESF_Worker.h"
00024 
00025 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00026 # pragma once
00027 #endif /* ACE_LACKS_PRAGMA_ONCE */
00028 
00029 #include "ace/Null_Mutex.h"
00030 #include "ace/RB_Tree.h"
00031 #include "ace/Map_Manager.h"
00032 
00033 #include "orbsvcs/RtecEventChannelAdminC.h"
00034 
00035 #include /**/ "orbsvcs/Event/event_serv_export.h"
00036 
00037 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00038 class ACE_Lock;
00039 ACE_END_VERSIONED_NAMESPACE_DECL
00040 
00041 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00042 
00043 class TAO_EC_Event_Channel_Base;
00044 class TAO_EC_ProxyPushConsumer;
00045 class TAO_EC_ProxyPushSupplier;
00046 
00047 /**
00048  * @class TAO_EC_ObserverStrategy
00049  *
00050  * @brief The strategy to handle observers for the Event Channel subscriptions
00051  * and publication.
00052  *
00053  * The Event Channel supports Observers for the set of subscriptions and
00054  * publications. This is used to implement federations of event channels,
00055  * either through UDP (multicast and unicast) and/or regular CORBA calls.
00056  * This behavior of the EC is strategized to avoid overhead when no gateways
00057  * are needed.
00058  */
00059 class TAO_RTEvent_Serv_Export TAO_EC_ObserverStrategy
00060 {
00061 public:
00062   /// Destructor
00063   virtual ~TAO_EC_ObserverStrategy (void);
00064 
00065   /// The basic methods to support the EC strategies.
00066   virtual RtecEventChannelAdmin::Observer_Handle
00067       append_observer (RtecEventChannelAdmin::Observer_ptr
00068                        ACE_ENV_ARG_DECL)
00069     ACE_THROW_SPEC ((
00070         CORBA::SystemException,
00071         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00072         RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER))
00073     = 0;
00074   virtual void remove_observer (
00075                         RtecEventChannelAdmin::Observer_Handle
00076                         ACE_ENV_ARG_DECL)
00077     ACE_THROW_SPEC ((
00078         CORBA::SystemException,
00079         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00080         RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER))
00081      = 0;
00082 
00083   /// Used by the EC to inform the ObserverStrategy that a Consumer has
00084   /// connected or disconnected from it.
00085   virtual void connected (TAO_EC_ProxyPushConsumer*
00086                           ACE_ENV_ARG_DECL_NOT_USED) = 0;
00087   virtual void disconnected (TAO_EC_ProxyPushConsumer*
00088                              ACE_ENV_ARG_DECL_NOT_USED) = 0;
00089 
00090   /// Used by the EC to inform the ObserverStrategy that a Supplier has
00091   /// connected or disconnected from it.
00092   virtual void connected (TAO_EC_ProxyPushSupplier*
00093                           ACE_ENV_ARG_DECL_NOT_USED) = 0;
00094   virtual void disconnected (TAO_EC_ProxyPushSupplier*
00095                              ACE_ENV_ARG_DECL_NOT_USED) = 0;
00096 };
00097 
00098 // ****************************************************************
00099 
00100 /**
00101  * @class TAO_EC_Null_ObserverStrategy
00102  *
00103  * @brief A null observer strategy.
00104  *
00105  * This class keeps no information and simply ignores the messages
00106  * from the EC.
00107  */
00108 class TAO_RTEvent_Serv_Export TAO_EC_Null_ObserverStrategy : public TAO_EC_ObserverStrategy
00109 {
00110 public:
00111   /// Constructor
00112   TAO_EC_Null_ObserverStrategy (void);
00113 
00114   // = The TAO_EC_ObserverStrategy methods.
00115   virtual RtecEventChannelAdmin::Observer_Handle
00116       append_observer (RtecEventChannelAdmin::Observer_ptr
00117                        ACE_ENV_ARG_DECL)
00118     ACE_THROW_SPEC ((
00119         CORBA::SystemException,
00120         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00121         RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER));
00122   virtual void remove_observer (
00123                         RtecEventChannelAdmin::Observer_Handle
00124                         ACE_ENV_ARG_DECL)
00125     ACE_THROW_SPEC ((
00126         CORBA::SystemException,
00127         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00128         RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER));
00129   virtual void connected (TAO_EC_ProxyPushConsumer*
00130                           ACE_ENV_ARG_DECL_NOT_USED);
00131   virtual void disconnected (TAO_EC_ProxyPushConsumer*
00132                              ACE_ENV_ARG_DECL_NOT_USED);
00133   virtual void connected (TAO_EC_ProxyPushSupplier*
00134                           ACE_ENV_ARG_DECL_NOT_USED);
00135   virtual void disconnected (TAO_EC_ProxyPushSupplier*
00136                              ACE_ENV_ARG_DECL_NOT_USED);
00137 };
00138 
00139 // ****************************************************************
00140 
00141 /**
00142  * @class TAO_EC_Basic_ObserverStrategy
00143  *
00144  * @brief A simple observer strategy.
00145  *
00146  * This class simply keeps the information about the current list
00147  * of observers, whenever the list of consumers and/or suppliers
00148  * changes in queries the EC, computes the global subscription
00149  * and/or publication list and sends the update message to all the
00150  * observers.
00151  *
00152  * <H2>Memory Management</H2>
00153  * It assumes ownership of the @a lock, but not of the
00154  * Event_Channel.
00155  */
00156 class TAO_RTEvent_Serv_Export TAO_EC_Basic_ObserverStrategy :
00157   public TAO_EC_ObserverStrategy
00158 {
00159 public:
00160   /// Constructor
00161   TAO_EC_Basic_ObserverStrategy (TAO_EC_Event_Channel_Base* ec,
00162                                  ACE_Lock* lock);
00163 
00164   /// Destructor
00165   virtual ~TAO_EC_Basic_ObserverStrategy (void);
00166 
00167   // = The TAO_EC_ObserverStrategy methods.
00168   virtual RtecEventChannelAdmin::Observer_Handle
00169       append_observer (RtecEventChannelAdmin::Observer_ptr
00170                        ACE_ENV_ARG_DECL)
00171     ACE_THROW_SPEC ((
00172         CORBA::SystemException,
00173         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00174         RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER));
00175   virtual void remove_observer (
00176                         RtecEventChannelAdmin::Observer_Handle
00177                         ACE_ENV_ARG_DECL)
00178     ACE_THROW_SPEC ((
00179         CORBA::SystemException,
00180         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
00181         RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER));
00182   virtual void connected (TAO_EC_ProxyPushConsumer*
00183                           ACE_ENV_ARG_DECL_NOT_USED);
00184   virtual void disconnected (TAO_EC_ProxyPushConsumer*
00185                              ACE_ENV_ARG_DECL_NOT_USED);
00186   virtual void connected (TAO_EC_ProxyPushSupplier*
00187                           ACE_ENV_ARG_DECL_NOT_USED);
00188   virtual void disconnected (TAO_EC_ProxyPushSupplier*
00189                              ACE_ENV_ARG_DECL_NOT_USED);
00190 
00191   /**
00192    * @struct Observer_Entry
00193    *
00194    * @brief  The data kept for each observer.
00195    *
00196    * The observer and its handle are kept in a simple structure.
00197    * In the future this structure could contain QoS information,
00198    * such as:
00199    * + how often do we update the observer?
00200    * + When was the last update.
00201    * + Does it want to receive all changes?
00202    */
00203   struct Observer_Entry
00204   {
00205     Observer_Entry (void);
00206     Observer_Entry (RtecEventChannelAdmin::Observer_Handle h,
00207                     RtecEventChannelAdmin::Observer_ptr o);
00208 
00209     /// The handle
00210     RtecEventChannelAdmin::Observer_Handle handle;
00211 
00212     /// The observer
00213     RtecEventChannelAdmin::Observer_var observer;
00214   };
00215 
00216   struct Header_Compare
00217   {
00218     int operator () (const RtecEventComm::EventHeader& lhs,
00219                      const RtecEventComm::EventHeader& rhs) const;
00220   };
00221 
00222   typedef ACE_Map_Manager<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map;
00223   typedef ACE_Map_Iterator<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map_Iterator;
00224 
00225 
00226   typedef ACE_RB_Tree<RtecEventComm::EventHeader,int,Header_Compare,ACE_Null_Mutex> Headers;
00227   typedef ACE_RB_Tree_Iterator<RtecEventComm::EventHeader,int,Header_Compare,ACE_Null_Mutex> HeadersIterator;
00228 
00229 protected:
00230   /// Helpers.
00231   //@{
00232   /// Recompute EC consumer subscriptions and send them out to all observers.
00233   virtual void consumer_qos_update (TAO_EC_ProxyPushSupplier *supplier
00234                                     ACE_ENV_ARG_DECL);
00235 
00236   /// Recompute EC supplier publications and send them out to all observers.
00237   virtual void supplier_qos_update (TAO_EC_ProxyPushConsumer *consumer
00238                                     ACE_ENV_ARG_DECL);
00239 
00240   /// Compute consumer QOS.
00241   void fill_qos (RtecEventChannelAdmin::ConsumerQOS &qos
00242                  ACE_ENV_ARG_DECL);
00243   /// Compute supplier QOS.
00244   void fill_qos (RtecEventChannelAdmin::SupplierQOS &qos
00245                  ACE_ENV_ARG_DECL);
00246 
00247   /// Copies all current observers into an array and passes it
00248   /// back to the caller through @a lst.  Returns the size of the array.
00249   int create_observer_list (RtecEventChannelAdmin::Observer_var *&lst
00250                             ACE_ENV_ARG_DECL);
00251   //@}
00252 
00253 protected:
00254   /// The event channel.
00255   TAO_EC_Event_Channel_Base* event_channel_;
00256 
00257   /// The lock
00258   ACE_Lock* lock_;
00259 
00260   /// The handles are generated in sequential order, but are opaque to
00261   /// the client.
00262   RtecEventChannelAdmin::Observer_Handle handle_generator_;
00263 
00264   /// Keep the set of Observers
00265   Observer_Map observers_;
00266 };
00267 
00268 // ****************************************************************
00269 
00270 /**
00271  * @class TAO_EC_Reactive_ObserverStrategy
00272  *
00273  * @brief A reactive observer strategy.
00274  *
00275  * This class simply keeps the information about the current list
00276  * of observers, whenever the list of consumers and/or suppliers
00277  * changes in queries the EC, computes the global subscription
00278  * and/or publication list and sends the update message to all the
00279  * observers. When an observer isn't reachable it is removed from
00280  * the observer list.
00281  *
00282  * <H2>Memory Management</H2>
00283  * It assumes ownership of the <lock>, but not of the
00284  * Event_Channel.
00285  */
00286 class TAO_RTEvent_Serv_Export TAO_EC_Reactive_ObserverStrategy :
00287   public TAO_EC_Basic_ObserverStrategy
00288 {
00289 public:
00290   /// Constructor
00291   TAO_EC_Reactive_ObserverStrategy (TAO_EC_Event_Channel_Base* ec,
00292                                     ACE_Lock* lock);
00293 
00294   /// Destructor
00295   virtual ~TAO_EC_Reactive_ObserverStrategy (void);
00296 
00297 protected:
00298   /// Helpers.
00299   //@{
00300   /// Recompute EC consumer subscriptions and send them out to all observers.
00301   virtual void consumer_qos_update (TAO_EC_ProxyPushSupplier *supplier
00302                                     ACE_ENV_ARG_DECL);
00303 
00304   /// Recompute EC supplier publications and send them out to all observers.
00305   virtual void supplier_qos_update (TAO_EC_ProxyPushConsumer *consumer
00306                                     ACE_ENV_ARG_DECL);
00307 
00308   /**
00309    * Copies all current observers into a map and passes it
00310    * back to the caller through @a map.
00311    * @return Returns the size of the map.
00312    */
00313   int create_observer_map (Observer_Map &map
00314                            ACE_ENV_ARG_DECL);
00315 
00316   /// The observer doesn't exist anymore
00317   void observer_not_exists (Observer_Entry& observer
00318                             ACE_ENV_ARG_DECL);
00319   //@}
00320 };
00321 
00322 // ****************************************************************
00323 
00324 class TAO_EC_Accumulate_Supplier_Headers :
00325   public TAO_ESF_Worker<TAO_EC_ProxyPushSupplier>
00326 {
00327 public:
00328   /// Constructor
00329   TAO_EC_Accumulate_Supplier_Headers (TAO_EC_Basic_ObserverStrategy::Headers &headers);
00330 
00331   virtual void work (TAO_EC_ProxyPushSupplier *supplier
00332                      ACE_ENV_ARG_DECL);
00333 
00334 private:
00335   TAO_EC_Basic_ObserverStrategy::Headers &headers_;
00336 };
00337 
00338 // ****************************************************************
00339 
00340 class TAO_EC_Accumulate_Consumer_Headers :
00341   public TAO_ESF_Worker<TAO_EC_ProxyPushConsumer>
00342 {
00343 public:
00344   /// Constructor
00345   TAO_EC_Accumulate_Consumer_Headers (TAO_EC_Basic_ObserverStrategy::Headers &headers);
00346 
00347   virtual void work (TAO_EC_ProxyPushConsumer *consumer
00348                      ACE_ENV_ARG_DECL);
00349 
00350 private:
00351   TAO_EC_Basic_ObserverStrategy::Headers &headers_;
00352 };
00353 
00354 TAO_END_VERSIONED_NAMESPACE_DECL
00355 
00356 #if defined (__ACE_INLINE__)
00357 #include "orbsvcs/Event/EC_ObserverStrategy.i"
00358 #endif /* __ACE_INLINE__ */
00359 
00360 #include /**/ "ace/post.h"
00361 
00362 #endif /* TAO_EC_OBSERVERSTRATEGY_H */

Generated on Thu Nov 9 13:11:08 2006 for TAO_RTEvent by doxygen 1.3.6