Reconnection_Registry.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 /**
00004  *  @file Reconnection_Registry.cpp
00005  *
00006  *  Reconnection_Registry.cpp,v 1.13 2006/03/14 06:14:34 jtc Exp
00007  *
00008  *  @author Dale Wilson <wilson_d@ociweb.com>
00009  */
00010 #include "orbsvcs/Notify/Reconnection_Registry.h"
00011 
00012 #include "tao/debug.h"
00013 #include "orbsvcs/Notify/Properties.h"
00014 #include "orbsvcs/Notify/Topology_Saver.h"
00015 #include "ace/Vector_T.h"
00016 //#define DEBUG_LEVEL 10
00017 #ifndef DEBUG_LEVEL
00018 # define DEBUG_LEVEL TAO_debug_level
00019 #endif
00020 
00021 
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 namespace TAO_Notify
00025 {
00026   const char REGISTRY_TYPE[] = "reconnect_registry";
00027   const char RECONNECT_ID[] = "ReconnectId";
00028   const char RECONNECT_IOR[] = "IOR";
00029   const char REGISTRY_CALLBACK_TYPE[] = "reconnect_callback";
00030 
00031   Reconnection_Registry::Reconnection_Registry (Topology_Parent & parent)
00032     : highest_id_(0)
00033   {
00034     // not the best technique, here.  Take advantage of "protected"
00035     Topology_Object::topology_parent_ = &parent;
00036   }
00037 
00038   Reconnection_Registry::~Reconnection_Registry ()
00039   {
00040   }
00041 
00042   //////////////////////////
00043   // During normal operation
00044 
00045   NotifyExt::ReconnectionRegistry::ReconnectionID
00046   Reconnection_Registry::register_callback (
00047     NotifyExt::ReconnectionCallback_ptr callback
00048     ACE_ENV_ARG_DECL)
00049   {
00050     //@@todo DO WE NEED THREAD SAFENESS?
00051     NotifyExt::ReconnectionRegistry::ReconnectionID next_id = ++highest_id_;
00052 
00053     if (DEBUG_LEVEL > 0)
00054     {
00055       ACE_DEBUG ((LM_DEBUG,
00056         ACE_TEXT ("(%P|%t) Reconnect registry: registering %d\n"),
00057         static_cast<int> (next_id)
00058         ));
00059     }
00060     TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance();
00061     CORBA::ORB_var orb = properties->orb ();
00062 
00063     CORBA::String_var cior = orb->object_to_string (callback ACE_ENV_ARG_PARAMETER);
00064     ACE_CHECK_RETURN (0);
00065     ACE_CString ior(cior.in ());
00066     if ( 0 != reconnection_registry_.bind (next_id, ior))
00067     {
00068       //todo throw something;
00069     }
00070     this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER);
00071     ACE_CHECK_RETURN (0);
00072 
00073     return next_id;
00074   }
00075 
00076   void
00077   Reconnection_Registry::unregister_callback (NotifyExt::ReconnectionRegistry::ReconnectionID id
00078     ACE_ENV_ARG_DECL)
00079   {
00080     if (DEBUG_LEVEL > 0)
00081     {
00082       ACE_DEBUG ((LM_DEBUG,
00083         ACE_TEXT ("(%P|%t) Reconnect registry: unregistering %d\n"),
00084         static_cast<int> (id)
00085         ));
00086     }
00087     if ( 0 != reconnection_registry_.unbind (id))
00088     {
00089       //@@todo  throw something
00090     }
00091     this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER);
00092     ACE_CHECK;
00093   }
00094 
00095   CORBA::Boolean
00096   Reconnection_Registry::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00097   {
00098     return CORBA::Boolean(1);
00099   }
00100 
00101   //////////////////////
00102   // During topology save
00103 
00104   void
00105   Reconnection_Registry::save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL)
00106   {
00107     bool change = this->self_changed_;
00108     this->self_changed_ = false;
00109     this->children_changed_ = false;
00110 
00111     NVPList attrs;
00112     //@@todo: bool want_all_children =
00113       saver.begin_object (0, REGISTRY_TYPE, attrs, change ACE_ENV_ARG_PARAMETER);
00114     ACE_CHECK;
00115 
00116     Reconnection_Registry_Type::ENTRY *entry;
00117     for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_);
00118       iter.next (entry);
00119       iter.advance ())
00120     {
00121       NVPList cattrs;
00122       if (DEBUG_LEVEL > 0)
00123       {
00124         ACE_DEBUG ((LM_DEBUG,
00125           ACE_TEXT ("(%P|%t) Reconnect registry: saving %d\n"),
00126           static_cast<int> (entry->ext_id_)
00127           ));
00128       }
00129       cattrs.push_back(NVP(RECONNECT_ID, entry->ext_id_));
00130       cattrs.push_back(NVP(RECONNECT_IOR, entry->int_id_));
00131       saver.begin_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE, cattrs, true ACE_ENV_ARG_PARAMETER);
00132       ACE_CHECK;
00133       saver.end_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE ACE_ENV_ARG_PARAMETER);
00134       ACE_CHECK;
00135     }
00136 // todo:
00137 //    for all deleted children
00138 //    {
00139 //      saver.delete_child(child_type, child_id);
00140 //    }
00141     saver.end_object (0, REGISTRY_TYPE ACE_ENV_ARG_PARAMETER);
00142   }
00143 
00144   ///////////////////////////////////////
00145   // During reload of persistent topology
00146 
00147   Topology_Object*
00148   Reconnection_Registry::load_child (const ACE_CString & type,
00149         CORBA::Long,
00150         const NVPList& attrs
00151         ACE_ENV_ARG_DECL_NOT_USED)
00152   {
00153     if (type == REGISTRY_CALLBACK_TYPE)
00154     {
00155       NotifyExt::ReconnectionRegistry::ReconnectionID id;
00156       ACE_CString ior;
00157       if (attrs.load (RECONNECT_ID, id) && attrs.load (RECONNECT_IOR, ior))
00158       {
00159         if (id > highest_id_)
00160         {
00161           highest_id_ = id;
00162 
00163           if (DEBUG_LEVEL > 0)
00164           {
00165             ACE_DEBUG ((LM_DEBUG,
00166               ACE_TEXT ("(%P|%t) Reconnect registry: reloading %d\n"),
00167               static_cast<int> (id)
00168               ));
00169           }
00170         }
00171         if ( 0 != reconnection_registry_.bind (id, ior))
00172         {
00173           //@@todo - throw something;
00174         }
00175       }
00176       else
00177       {
00178         ACE_ERROR ((LM_ERROR,
00179           ACE_TEXT ("(%P|%t) Reconnect registry: missing attribute\n")
00180           ));
00181       }
00182     }
00183     return this;
00184   }
00185 
00186   void
00187   Reconnection_Registry::send_reconnect (CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory
00188     ACE_ENV_ARG_DECL_NOT_USED)
00189   {
00190     TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance();
00191     CORBA::ORB_var orb = properties->orb ();
00192     ACE_Vector <NotifyExt::ReconnectionRegistry::ReconnectionID> bad_ids;
00193 
00194     Reconnection_Registry_Type::ENTRY *entry;
00195     for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_);
00196       iter.next (entry);
00197       iter.advance ())
00198     {
00199       ACE_DECLARE_NEW_ENV;
00200       ACE_TRY
00201       {
00202         if (DEBUG_LEVEL > 0)
00203         {
00204           ACE_DEBUG ((LM_DEBUG,
00205             ACE_TEXT ("(%P|%t) Reconnection Registry: Sending reconnection to client %d\n"),
00206               static_cast<int> (entry->ext_id_)
00207             ));
00208         }
00209         ACE_CString & ior = entry->int_id_;
00210         CORBA::Object_var obj = orb->string_to_object (ior.c_str () ACE_ENV_ARG_PARAMETER);
00211         ACE_TRY_CHECK;
00212         NotifyExt::ReconnectionCallback_var callback =
00213           NotifyExt::ReconnectionCallback::_narrow (obj.in ());
00214         if (!CORBA::is_nil (callback.in ()))
00215         {
00216           callback->reconnect (dest_factory ACE_ENV_ARG_PARAMETER);
00217           ACE_TRY_CHECK;
00218         }
00219         else
00220         {
00221           ACE_DEBUG ((LM_DEBUG,
00222             ACE_TEXT ("(%P|%t) Reconnection Registry: Can't resolve reconnection client's IOR %d\n"),
00223               static_cast<int> (entry->ext_id_)
00224             ));
00225 
00226           //throw this entry away but you've got an iterator so be careful
00227           bad_ids.push_back (entry->ext_id_);
00228         }
00229       }
00230       ACE_CATCHANY
00231       {
00232         ACE_DEBUG ((LM_DEBUG,
00233           ACE_TEXT ("(%P|%t) Reconnection Registry: Exception sending reconnection to client -- discarding registry entry\n")
00234           ));
00235         //throw this entry away but you've got an iterator so be careful
00236         bad_ids.push_back (entry->ext_id_);
00237         //@@todo : we might want to check for retryable exceptions, but for now...
00238       }
00239       ACE_ENDTRY;
00240     }
00241     size_t bad_count = bad_ids.size ();
00242     for (size_t nbad = 0; nbad < bad_count; ++nbad)
00243     {
00244       this->reconnection_registry_.unbind (bad_ids[nbad]);
00245     }
00246   }
00247 
00248   void
00249   Reconnection_Registry::release (void)
00250   {
00251     delete this;
00252     //@@ inform factory
00253   }
00254 
00255 } // namespace TAO_Notify
00256 
00257 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:24:15 2006 for TAO_CosNotification by doxygen 1.3.6