EC_ObserverStrategy.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 /**
00004  *  @file   EC_ObserverStrategy.h
00005  *
00006  *  $Id: EC_ObserverStrategy.h 77001 2007-02-12 07:54:49Z johnnyw $
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     = 0;
00069   virtual void remove_observer (
00070                         RtecEventChannelAdmin::Observer_Handle)
00071      = 0;
00072 
00073   /// Used by the EC to inform the ObserverStrategy that a Consumer has
00074   /// connected or disconnected from it.
00075   virtual void connected (TAO_EC_ProxyPushConsumer*) = 0;
00076   virtual void disconnected (TAO_EC_ProxyPushConsumer*) = 0;
00077 
00078   /// Used by the EC to inform the ObserverStrategy that a Supplier has
00079   /// connected or disconnected from it.
00080   virtual void connected (TAO_EC_ProxyPushSupplier*) = 0;
00081   virtual void disconnected (TAO_EC_ProxyPushSupplier*) = 0;
00082 };
00083 
00084 // ****************************************************************
00085 
00086 /**
00087  * @class TAO_EC_Null_ObserverStrategy
00088  *
00089  * @brief A null observer strategy.
00090  *
00091  * This class keeps no information and simply ignores the messages
00092  * from the EC.
00093  */
00094 class TAO_RTEvent_Serv_Export TAO_EC_Null_ObserverStrategy : public TAO_EC_ObserverStrategy
00095 {
00096 public:
00097   /// Constructor
00098   TAO_EC_Null_ObserverStrategy (void);
00099 
00100   // = The TAO_EC_ObserverStrategy methods.
00101   virtual RtecEventChannelAdmin::Observer_Handle
00102       append_observer (RtecEventChannelAdmin::Observer_ptr);
00103   virtual void remove_observer (
00104                         RtecEventChannelAdmin::Observer_Handle);
00105   virtual void connected (TAO_EC_ProxyPushConsumer*);
00106   virtual void disconnected (TAO_EC_ProxyPushConsumer*);
00107   virtual void connected (TAO_EC_ProxyPushSupplier*);
00108   virtual void disconnected (TAO_EC_ProxyPushSupplier*);
00109 };
00110 
00111 // ****************************************************************
00112 
00113 /**
00114  * @class TAO_EC_Basic_ObserverStrategy
00115  *
00116  * @brief A simple observer strategy.
00117  *
00118  * This class simply keeps the information about the current list
00119  * of observers, whenever the list of consumers and/or suppliers
00120  * changes in queries the EC, computes the global subscription
00121  * and/or publication list and sends the update message to all the
00122  * observers.
00123  *
00124  * <H2>Memory Management</H2>
00125  * It assumes ownership of the @a lock, but not of the
00126  * Event_Channel.
00127  */
00128 class TAO_RTEvent_Serv_Export TAO_EC_Basic_ObserverStrategy :
00129   public TAO_EC_ObserverStrategy
00130 {
00131 public:
00132   /// Constructor
00133   TAO_EC_Basic_ObserverStrategy (TAO_EC_Event_Channel_Base* ec,
00134                                  ACE_Lock* lock);
00135 
00136   /// Destructor
00137   virtual ~TAO_EC_Basic_ObserverStrategy (void);
00138 
00139   // = The TAO_EC_ObserverStrategy methods.
00140   virtual RtecEventChannelAdmin::Observer_Handle
00141       append_observer (RtecEventChannelAdmin::Observer_ptr);
00142   virtual void remove_observer (
00143                         RtecEventChannelAdmin::Observer_Handle);
00144   virtual void connected (TAO_EC_ProxyPushConsumer*);
00145   virtual void disconnected (TAO_EC_ProxyPushConsumer*);
00146   virtual void connected (TAO_EC_ProxyPushSupplier*);
00147   virtual void disconnected (TAO_EC_ProxyPushSupplier*);
00148 
00149   /**
00150    * @struct Observer_Entry
00151    *
00152    * @brief  The data kept for each observer.
00153    *
00154    * The observer and its handle are kept in a simple structure.
00155    * In the future this structure could contain QoS information,
00156    * such as:
00157    * + how often do we update the observer?
00158    * + When was the last update.
00159    * + Does it want to receive all changes?
00160    */
00161   struct Observer_Entry
00162   {
00163     Observer_Entry (void);
00164     Observer_Entry (RtecEventChannelAdmin::Observer_Handle h,
00165                     RtecEventChannelAdmin::Observer_ptr o);
00166 
00167     /// The handle
00168     RtecEventChannelAdmin::Observer_Handle handle;
00169 
00170     /// The observer
00171     RtecEventChannelAdmin::Observer_var observer;
00172   };
00173 
00174   struct Header_Compare
00175   {
00176     int operator () (const RtecEventComm::EventHeader& lhs,
00177                      const RtecEventComm::EventHeader& rhs) const;
00178   };
00179 
00180   typedef ACE_Map_Manager<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map;
00181   typedef ACE_Map_Iterator<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map_Iterator;
00182 
00183 
00184   typedef ACE_RB_Tree<RtecEventComm::EventHeader,int,Header_Compare,ACE_Null_Mutex> Headers;
00185   typedef ACE_RB_Tree_Iterator<RtecEventComm::EventHeader,int,Header_Compare,ACE_Null_Mutex> HeadersIterator;
00186 
00187 protected:
00188   /// Helpers.
00189   //@{
00190   /// Recompute EC consumer subscriptions and send them out to all observers.
00191   virtual void consumer_qos_update (TAO_EC_ProxyPushSupplier *supplier);
00192 
00193   /// Recompute EC supplier publications and send them out to all observers.
00194   virtual void supplier_qos_update (TAO_EC_ProxyPushConsumer *consumer);
00195 
00196   /// Compute consumer QOS.
00197   void fill_qos (RtecEventChannelAdmin::ConsumerQOS &qos);
00198   /// Compute supplier QOS.
00199   void fill_qos (RtecEventChannelAdmin::SupplierQOS &qos);
00200 
00201   /// Copies all current observers into an array and passes it
00202   /// back to the caller through @a lst.  Returns the size of the array.
00203   int create_observer_list (RtecEventChannelAdmin::Observer_var *&lst);
00204   //@}
00205 
00206 protected:
00207   /// The event channel.
00208   TAO_EC_Event_Channel_Base* event_channel_;
00209 
00210   /// The lock
00211   ACE_Lock* lock_;
00212 
00213   /// The handles are generated in sequential order, but are opaque to
00214   /// the client.
00215   RtecEventChannelAdmin::Observer_Handle handle_generator_;
00216 
00217   /// Keep the set of Observers
00218   Observer_Map observers_;
00219 };
00220 
00221 // ****************************************************************
00222 
00223 /**
00224  * @class TAO_EC_Reactive_ObserverStrategy
00225  *
00226  * @brief A reactive observer strategy.
00227  *
00228  * This class simply keeps the information about the current list
00229  * of observers, whenever the list of consumers and/or suppliers
00230  * changes in queries the EC, computes the global subscription
00231  * and/or publication list and sends the update message to all the
00232  * observers. When an observer isn't reachable it is removed from
00233  * the observer list.
00234  *
00235  * <H2>Memory Management</H2>
00236  * It assumes ownership of the <lock>, but not of the
00237  * Event_Channel.
00238  */
00239 class TAO_RTEvent_Serv_Export TAO_EC_Reactive_ObserverStrategy :
00240   public TAO_EC_Basic_ObserverStrategy
00241 {
00242 public:
00243   /// Constructor
00244   TAO_EC_Reactive_ObserverStrategy (TAO_EC_Event_Channel_Base* ec,
00245                                     ACE_Lock* lock);
00246 
00247   /// Destructor
00248   virtual ~TAO_EC_Reactive_ObserverStrategy (void);
00249 
00250 protected:
00251   /// Helpers.
00252   //@{
00253   /// Recompute EC consumer subscriptions and send them out to all observers.
00254   virtual void consumer_qos_update (TAO_EC_ProxyPushSupplier *supplier);
00255 
00256   /// Recompute EC supplier publications and send them out to all observers.
00257   virtual void supplier_qos_update (TAO_EC_ProxyPushConsumer *consumer);
00258 
00259   /**
00260    * Copies all current observers into a map and passes it
00261    * back to the caller through @a map.
00262    * @return Returns the size of the map.
00263    */
00264   int create_observer_map (Observer_Map &map);
00265 
00266   /// The observer doesn't exist anymore
00267   void observer_not_exists (Observer_Entry& observer);
00268   //@}
00269 };
00270 
00271 // ****************************************************************
00272 
00273 class TAO_EC_Accumulate_Supplier_Headers :
00274   public TAO_ESF_Worker<TAO_EC_ProxyPushSupplier>
00275 {
00276 public:
00277   /// Constructor
00278   TAO_EC_Accumulate_Supplier_Headers (TAO_EC_Basic_ObserverStrategy::Headers &headers);
00279 
00280   virtual void work (TAO_EC_ProxyPushSupplier *supplier);
00281 
00282 private:
00283   TAO_EC_Basic_ObserverStrategy::Headers &headers_;
00284 };
00285 
00286 // ****************************************************************
00287 
00288 class TAO_EC_Accumulate_Consumer_Headers :
00289   public TAO_ESF_Worker<TAO_EC_ProxyPushConsumer>
00290 {
00291 public:
00292   /// Constructor
00293   TAO_EC_Accumulate_Consumer_Headers (TAO_EC_Basic_ObserverStrategy::Headers &headers);
00294 
00295   virtual void work (TAO_EC_ProxyPushConsumer *consumer);
00296 
00297 private:
00298   TAO_EC_Basic_ObserverStrategy::Headers &headers_;
00299 };
00300 
00301 TAO_END_VERSIONED_NAMESPACE_DECL
00302 
00303 #if defined (__ACE_INLINE__)
00304 #include "orbsvcs/Event/EC_ObserverStrategy.inl"
00305 #endif /* __ACE_INLINE__ */
00306 
00307 #include /**/ "ace/post.h"
00308 
00309 #endif /* TAO_EC_OBSERVERSTRATEGY_H */

Generated on Tue Feb 2 17:44:05 2010 for TAO_RTEvent by  doxygen 1.4.7