diff options
author | Ossama Othman <ossama-othman@users.noreply.github.com> | 2001-06-15 16:55:31 +0000 |
---|---|---|
committer | Ossama Othman <ossama-othman@users.noreply.github.com> | 2001-06-15 16:55:31 +0000 |
commit | e7c92e7379041715206d05bfd822df80e4c8b50a (patch) | |
tree | 13750bc1f792b72fd899c453fc01d932058c5108 | |
parent | cfb1ef27ea0d516eedc67cee490d9fcfd2ac5ff9 (diff) | |
download | ATCD-e7c92e7379041715206d05bfd822df80e4c8b50a.tar.gz |
*** empty log message ***
31 files changed, 1809 insertions, 66 deletions
diff --git a/TAO/orbsvcs/orbsvcs/LB_GenericFactory.cpp b/TAO/orbsvcs/orbsvcs/LB_GenericFactory.cpp index 753de0ee129..4a14567477f 100644 --- a/TAO/orbsvcs/orbsvcs/LB_GenericFactory.cpp +++ b/TAO/orbsvcs/orbsvcs/LB_GenericFactory.cpp @@ -1,6 +1,8 @@ // -*- C++ -*- #include "LB_GenericFactory.h" +#include "LB_ReplicaInfo.h" + ACE_RCSID (LoadBalancing, LB_GenericFactory, @@ -141,39 +143,44 @@ TAO_LB_GenericFactory::delete_object ( if (this->object_group_map_.find (fcid, object_group) == -1) ACE_THROW (LoadBalancing::ObjectNotFound ()); - TAO_LB_Replica_Map *replica_map = object_group->replica_map; + TAO_LB_ReplicaInfo_Set &replica_infos = object_group->replica_infos; - for (TAO_LB_Replica_Map::Table::iterator i = replica_map->begin (); - i != replica_map->end (); - ++i) - { - TAO_LB_Replica_Map_Entry *replica = (*i).ext_id_; + { + ACE_GUARD (TAO_SYNCH_MUTEX, guard, object_group->lock); + for (TAO_LB_ReplicaInfoSetIterator i = replica_infos.begin (); + i != replica_infos.end (); + ++i) + { + TAO_LB_ReplicaInfo *replica_info = (*i).ext_id_; - LoadBalancing::GenericFactory_ptr factory = - replica->factory.in (); + LoadBalancing::GenericFactory_ptr factory = + replica_info->factory_info.the_factory.in (); - if (!CORBA::is_nil (factory)) - { - LoadBalancing::GenericFactory::FactoryCreationId - &replica_fcid = replica->factory_creation_id; + // If the factory reference is not nil, then the replica + // was created using a GenericFactory. Make sure that + // factory deletes it. + if (!CORBA::is_nil (factory)) + { + LoadBalancing::GenericFactory::FactoryCreationId + &replica_fcid = replica_info->factory_creation_id; - factory->delete_object (replica_fcid.in, ACE_TRY_ENV); - ACE_CHECK; - } + factory->delete_object (replica_fcid.in (), ACE_TRY_ENV); + ACE_CHECK; + } - - (void) replica_map->unbind (&(*i)); + (void) replica_info->unbind (&(*i)); - delete replica_map; - } + delete replica_info; + } + } // Now delete the ObjectGroup from the set of ObjectGroups. this->object_group_map_.unbind (fcid); delete object_group; } - - ACE_THROW (LoadBalancing::ObjectNotFound ()); + else + ACE_THROW (LoadBalancing::ObjectNotFound ()); } void @@ -184,7 +191,7 @@ TAO_LB_GenericFactory::populate_object_group ( for (CORBA::ULong j = 0; j < factory_infos_count; ++j) { // The FactoryInfo::the_location member was used when - // determining which FactoryInfo + // determining which FactoryInfo // member? // @@ It looks like it is only used when the application // control membership style is used. The application @@ -270,7 +277,7 @@ TAO_LB_GenericFactory::populate_object_group ( } // No longer need to protect the allocated Replica_Map. - safe_replica_entry.release (); + safe_replica_info.release (); } } diff --git a/TAO/orbsvcs/orbsvcs/LB_GenericFactory.h b/TAO/orbsvcs/orbsvcs/LB_GenericFactory.h index 0ed484b8656..811d5974fbe 100644 --- a/TAO/orbsvcs/orbsvcs/LB_GenericFactory.h +++ b/TAO/orbsvcs/orbsvcs/LB_GenericFactory.h @@ -35,8 +35,12 @@ class TAO_LB_ObjectGroup_Map; /** * @class TAO_LB_GenericFactory * - * @brief + * @brief LoadBalancing::GenericFactory implementation used by the + * load balancer when creating object groups. * + * This GenericFactory creates an object group reference for given set + * of replicas. Those replicas will be created by this GenericFactory + * if the "infrastructure-controlled" membership style is configured. */ class TAO_LB_GenericFactory : public virtual LoadBalancing::GenericFactory diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h index 3de656e0788..07843e8f37e 100644 --- a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h @@ -25,7 +25,7 @@ #include "ace/Hash_Map_Manager_T.h" #include "orbsvcs/LoadBalancingC.h" -#include "LB_Replica_Set.h" +#include "LB_ReplicaInfo_Set.h" /** @@ -37,13 +37,12 @@ */ class TAO_LB_ObjectGroup_Map { - public: /** * @class Map_Entry * - * @brief Value field of the replica map. + * @brief Value field of the ObjectGroup map. * * Mapping from and to all of the following fields: * @param object_group, @param factory_creation_id, @param factory, @@ -57,11 +56,14 @@ public: CORBA::String_var type_id; /// Reference to the ObjectGroup. - TAO_LoadBalancing::ObjectGroup_var object_group; + LoadBalancing::ObjectGroup_var object_group; /// Unbounded set containing replica references and all related /// information for each replica. TAO_LB_ReplicaInfo_Set replica_infos; + + /// Lock used to synchronize access to the ReplicaInfo set. + TAO_SYNCH_MUTEX lock; }; /// FactoryCreationId hash map. A FactoryCreationId is represented diff --git a/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.cpp b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.cpp new file mode 100644 index 00000000000..99604af4fa7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.cpp @@ -0,0 +1,90 @@ +// -*- C++ -*- + +#include "LB_RPMS_Monitor.h" + + +ACE_RCSID (LoadBalancing, + LB_RPMS_Monitor, + "$Id$") + +TAO_LB_RPMS_Monitor::TAO_LB_RPMS_Monitor (void) +{ +} + +void +TAO_LB_RPMS_Monitor::init (CORBA::Environment &ACE_TRY_ENV) +{ + // Possibly no CORBA exceptions instantiated yet so don't attempt + // to throw one if allocation fails. + + TAO_LB_RPMS_Monitor_Interceptor *& interceptor = + this->interceptor_.out (); + + ACE_NEW (interceptor, + TAO_LB_RPMS_Monitor_Interceptor (this->object_group_.in ())); + + TAO_LB_RPMS_Monitor_ORBInitializer *initializer = 0; + ACE_NEW (temp_initializer, + TAO_LB_RPMS_Monitor_ORBInitializer (this->interceptor_.in ())); + + PortableInterceptor::ORBInitializer_var orb_initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (initializer.in (), + ACE_TRY_ENV); + ACE_CHECK; +} + +LoadBalancing::LoadList * +TAO_LB_RPMS_Monitor::current_load (CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Construct the LoadList here instead of inside the interceptor to + // maximize throughput in a multithreaded server replica by + // preventing two allocations from being added to the critical path + // of the client request. + // + // This optimization won't make a difference on single-threaded + // server replicas. + + LoadBalancing::LoadList *tmp_loads = 0; + ACE_NEW_THROW_EX (LoadBalancing::LoadList, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (0); + + LoadBalancing::LoadList_var loads = tmps_loads; + + loads->length (1); + + // The LoadId should be unique within the location this monitor + // resides. + loads[0].identifier = 0; // @todo Use a symbolic constant instead. + + loads[0].value = this->interceptor_->current_load (); + + return loads._retn (); +} + +void +TAO_LB_RPMS_Monitor::register_redirect (const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->interceptor_.register_redirect (type_id, + redirect_to, + ACE_TRY_ENV); +} + +void +TAO_LB_RPMS_Monitor::remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->interceptor_.remove_redirect (type_id, + ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.h b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.h new file mode 100644 index 00000000000..31f6a2705e6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor.h @@ -0,0 +1,88 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_RPMS_Monitor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_RPMS_MONITOR_H +#define TAO_LB_RPMS_MONITOR_H + +#include "ace/pre.h" + +#include "LoadBalancing_export.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/LoadBalancingS.h" + +#include "LB_RPMS_Monitor_Interceptor.h" + + +/** + * @class TAO_LB_RPMS_Monitor + * + * @brief LoadMonitor implementation that returns monitor the number + * of requests per second a given location receives. + * + * Since interceptors are locality-constrained, the Load Balancer + * actually makes feedback and control invocations methods through + * this LoadMonitor exposed by this LoadMonitor. This LoadMonitor + * basically delegates all of its work on to its underlying + * ServerRequestInterceptor. + */ +class TAO_LoadBalancing_Export TAO_LB_RPMS_Monitor + : public virtual POA_LoadBalancing::LoadMonitor +{ +public: + + /// Constructor + TAO_LB_RPMS_Monitor (void); + + /** + * @name LoadBalancing::LoadMonitor Methods + */ + //@{ + + /// Return the number of requests per second arriving at the + /// location this load monitor resides. + virtual LoadBalancing::LoadList *current_load ( + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Force redirection of requests for targets with the given + /// RepositoryId to the target pointed to by the given object + /// reference. + virtual void register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove the redirect for targets of the given RepositoryId. + virtual void remove_redirect ( + const char *type_id, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + +private: + + /// Interceptor responsible for keeping track of the number of + /// requests arriving per second. + TAO_LB_RPMS_Monitor_Interceptor_var interceptor_; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_RPMS_MONITOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.cpp b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.cpp new file mode 100644 index 00000000000..c8c9d5f2af7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.cpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +#include "LB_RPMS_Monitor_Interceptor.h" + +ACE_RCSID (LoadBalancing, + LB_RPMS_Monitor_Interceptor, + "$Id$") + + +#if defined (__ACE_INLINE__) +# include "LB_RPMS_Monitor_Interceptor.inl" +#endif /* __ACE_INLINE__ */ + + +TAO_LB_RPMS_Monitor_Interceptor::TAO_LB_RPMS_Monitor_Interceptor ( + CORBA::Object_ptr object_group) + : lock_ (), + redirect_table_ (), + request_count_ (0), + interval_start_ (ACE_OS::gettimeofday ()), + object_group_ () +{ +} + +char * +TAO_LB_RPMS_Monitor_Interceptor::name (TAO_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // @todo It might be necessary to use an anonymous interceptor, + // i.e. an interceptor whose name is the empty string ("") in + // case multiple interceptors of this type are registered with + // an ORB. + return CORBA::string_dup ("TAO_LB_RPMS_Monitor_Interceptor"); +} + +void +TAO_LB_RPMS_Monitor_Interceptor::destroy (TAO_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->redirect_table_.destroy (); +} + +void +TAO_LB_RPMS_Monitor_Interceptor::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + TAO_ENV_ARG_DEFN; + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + ++this->request_count_; + + // If required to do so by the load balancer, redirect all + // requests back to the target corresponding to the RepositoryId in + // redirect table. + this->redirect_table_.find_redirect (ri, + ACE_TRY_ENV); + ACE_CHECK; +} + +void +TAO_LB_RPMS_Monitor_Interceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_other ( + PortableInterceptor::ServerRequestInfo_ptr + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.h b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.h new file mode 100644 index 00000000000..cb0a7ccb247 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.h @@ -0,0 +1,159 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_RPMS_Monitor_Interceptor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_RPMS_MONITOR_INTERCEPTOR_H +#define TAO_LB_RPMS_MONITOR_INTERCEPTOR_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#includ "ace/Sync.h" + +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" + +/** + * @class TAO_LB_RPMS_Monitor_Interceptor + * + * @brief ServerRequestInterceptor that provides feedback and + * control. + * + * This ServerRequestInterceptor is used to count the number of + * requests per millisecond that are arriving at the location this + * interceptor resides. + */ +class TAO_LB_RPMS_Monitor_Interceptor + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual TAO_Local_RefCounted_Object +{ +public: + + /// Constructor + TAO_LB_RPMS_Monitor (void); + + /** + * @name Methods Required by the ServerRequestInterceptor + * Interface + * + * These are methods that must be implemented since they are pure + * virtual in the abstract base class. They are the canonical + * methods required for all server request interceptors. + */ + //@{ + + virtual char * name (TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy (TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// The bulk of the work this interceptor implementations performs + /// is in this interception point. + virtual void receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + //@} + + /** + * @name Feedback and control methods. + * + * Methods that indirectly provide feedback and control to the load + * balancer via the load monitor. + */ + //@{ + + /// Return the current average load (requests per second). + CORBA::Float current_load (void) const; + + /// Force redirection of requests for targets with the given + /// RepositoryId to the target pointed to by the given object + /// reference. + void register_redirect (const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV); + + /// Remove the redirect for targets of the given RepositoryId. + void remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV); + + //@} + +public: + + /// This template is actually instantiated in + /// `tao/Object_Ref_Table.cpp'. + typedef ACE_Hash_Map_Manager_Ex<const char *, CORBA::Object_ptr, ACE_Hash<const char *>, ACE_Equal_To<const char *>, ACE_Null_Mutex> Table; + +private: + + /// Lock that forces access request count to be modified/accessed + /// atomically. + TAO_SYNCH_MUTEX lock_; + + /// Flag that if set true will cause this interceptor to redirect + /// all requests back to the load balancer. + CORBA::Boolean redirect_requests_; + + /// The number of requests received at the location this interceptor + /// resides in the current measurement interval. + CORBA::ULong request_count_; + + // The start of the current measurement interval. + ACE_Time_Value interval_start_; + + /// Reference to the Load Balancer. + LoadBalancing::ReplicationManager_var lb_; + + + +}; + + +#if defined (__ACE_INLINE__) +# include "LB_RPMS_Monitor_Interceptor.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/post.h" + +#endif /* TAO_LB_RPMS_MONITOR_INTERCEPTOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.inl b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.inl new file mode 100644 index 00000000000..4cd431f4f15 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_RPMS_Monitor_Interceptor.inl @@ -0,0 +1,45 @@ +// -*- C++ -*- + +ACE_INLINE CORBA::Float +TAO_LB_RPMS_Monitor_Interceptor::current_load (void) const +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + ACE_Time_Value elapsed_time = + ACE_OS::gettimeofday () - this->interval_start_; + + this->interval_start_ = ACE_OS::gettimeofday (); + + CORBA::Float load = + ACE_static_cast (CORBA::Float, + this->request_count_) / elapsed_time.msec (); + + this->request_count_ = 0; + this->interval_start_ = ACE_OS::gettimeofday (); + + return load; +} + +ACE_INLINE void +TAO_LB_RPMS_Monitor_Interceptor::register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->redirect_table_.register_redirect (type_id, + redirect_to, + ACE_TRY_ENV); +} + +ACE_INLINE void +TAO_LB_RPMS_Monitor_Interceptor::remove_redirect ( + const char *type_id, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->redirect_table_.remove_redirect (type_id, + ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.cpp b/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.cpp new file mode 100644 index 00000000000..9a6b33d519a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.cpp @@ -0,0 +1,180 @@ +// -*- C++ -*- + +#include "LB_Redirect_Table.h" +#include "Object.h" +#include "Exception.h" +#include "Environment.h" +#include "CORBA_String.h" +#include "debug.h" + +ACE_RCSID (LoadBalancing, + LB_Redirect_Table, + "$Id$") + +// **************************************************************** + +TAO_LB_Redirect_Table::TAO_LB_Redirect_Table (void) + : table_ () +{ +} + +TAO_LB_Redirect_Table::~TAO_LB_Redirect_Table (void) +{ + // Must explicitly call destroy() in the destructor since not all + // applications will invoke ORB::shutdown() or ORB::destroy(). + this->destroy (); +} + +void +TAO_LB_Redirect_Table::register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) +{ + // The RepositoryId should never be zero since it is not possible to + // send a NULL string as an "in" argument. + if (ACE_OS_String::strlen (id) == 0) + ACE_THROW (CORBA::BAD_PARAM ()); + + if (CORBA::is_nil (obj)) + ACE_THROW (CORBA::BAD_PARAM ()); + + int result = this->bind (type_id, redirect_to); + + if (result == 1) + { + if (TAO_debug_level > 1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) LB_Redirect_Table::register_redirect:\n" + " Could not register duplicate object <%s> with " + "the LB_Redirect_Table\n", + type_id)); + + ACE_THROW (CORBA::INV_OBJREF ()); + } + + if (result == -1) + { + if (TAO_debug_level > 1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) LB_Redirect_Table::register_redirect:\n" + " Could not register redirect object <%s> with " + "the LB_Redirect_Table\n", + type_id)); + + ACE_THROW (CORBA::INTERNAL ()); + } +} + +void +TAO_LB_Redirect_Table::find_redirect ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::Environment &ACE_TRY_ENV) +{ + // This could become very slow if there are many type of targets + // being redirected since we're doing a linear search using string + // comparisons. + // + // We do things this way to avoid the memory allocation that would + // occur if we were to just use the + // ServerRequestInfo::target_most_derived_interface() method. At + // some point, there is a threshold reached where the cost of the + // iteration through the redirect table is more expensive than the + // allocation incurred by calling + // ServerRequestInfo::target_most_derived_interface(). That + // threshold is approached as the number of redirects in the table + // becomes "large." For now, we optimize for the common case and + // assume that only a few types of targets (i.e. objects/servants + // with different RepositoryIds) exist at the current location. + // + // Note that if no redirects are registered, then this method + // basically becomes a no-op. + + for (Table::iterator i = this->table_.begin (); + i != this->table_.end (); + ++i) + { + // Compare the target's RepositoryId with the registered + // redirects. + CORBA::Boolean matched = + ri->target_is_a ((*i).ext_id_, ACE_TRY_ENV); + ACE_CHECK_RETURN (0); + + if (matched) + ACE_THROW (PortableInterceptor::ForwardRequest ( + (*i).int_id_, + 0 /* non-permanent forward */)); + } +} + +int +TAO_LB_Redirect_Table::remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV) +{ + Table::ENTRY *entry = 0; + + int result = this->table_.find (type_id, entry); + + if (result == 0) + { + // Deallocate the external ID and obtain the ORB core pointer + // before unbinding the entry since the entry is deallocated + // during the call to unbind(). + CORBA::string_free (ACE_const_cast (char *, entry->ext_id_)); + CORBA::Object_ptr redirect = entry->int_id_; + + result = this->table_.unbind (entry); + + if (result != 0) + return result; + + CORBA::release (redirect); + } + + return result; +} + +void +TAO_LB_Redirect_Table::destroy (void) +{ + for (Table::iterator i = this->table_.begin (); + i != this->table_.end (); + ++i) + { + // Deallocate the id. + CORBA::string_free (ACE_const_cast (char *, (*i).ext_id_)); + + // Release the Object. + CORBA::release ((*i).int_id_); + } + + this->table_.unbind_all (); +} + +int +TAO_LB_Redirect_Table::bind (const char *id, + CORBA::Object_ptr obj) +{ + // Make sure that the supplied Object reference is valid, + // i.e. not nil. + if (id == 0 || CORBA::is_nil (obj)) + { + errno = EINVAL; + return -1; + }; + + CORBA::String_var type_id = CORBA::string_dup (id); + CORBA::Object_var redirect = CORBA::Object::_duplicate (obj); + + int result = this->table_.bind (type_id.in (), + redirect.in ()); + + if (result == 0) + { + // Transfer ownership to the Object Table. + (void) type_id._retn (); + (void) redirect._retn (); + } + + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.h b/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.h new file mode 100644 index 00000000000..0b3d6d09161 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Redirect_Table.h @@ -0,0 +1,100 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_Redirect_Table.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_REDIRECT_TABLE_H +#define TAO_LB_REDIRECT_TABLE_H + +#include "ace/pre.h" + +#include "corbafwd.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Functor.h" + + +/** + * @class TAO_LB_Redirect_Table + * + * @brief Maintain a table of "redirects" corresponding to a target + * with the given RepositoryId. + * + * If a table entry for the given RepositoryId exists, then the load + * monitor will redirect the client request to the target pointed to + * by the object reference in that entry. + * + * It is necessary to maintain a redirect table since the load + * balancer determines which object group to select a replica from by + * examining the target's object ID. As such a request cannot simply + * be forwarded back to the load balancer without knowing what its + * intended target (i.e. object group) is. This table keeps track of + * the object group reference to which a replica of a given type + * belongs. + */ +class TAO_LB_Redirect_Table +{ +public: + + typedef ACE_Hash_Map_Manager_Ex<const char *, CORBA::Object_ptr, ACE_Hash<const char *>, ACE_Equal_To<const char *>, ACE_Null_Mutex> Table; + + /// Constructor + TAO_LB_Redirect_Table (void); + + /// Destructor + ~TAO_LB_Redirect_Table (void); + + /// Register an object reference with the table, and map the given + /// ID to it. + void register_redirect (const char * type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV); + + /// Remove the redirect associated with the given RepositoryId. + void remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV); + + /// Check if a redirect exists for the current target. If so, then + /// perform the request redirection by throwing a + /// PortableInterceptor::ForwardRequest exception. + void find_redirect (PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::Environment &ACE_TRY_ENV); + + /// Reclaim the resources held by this table (deallocate strings, + /// release object references, etc). + void destroy (void); + +private: + + /// Helper method that binds the redirect to the given RepositoryId. + int bind (const char *type_id, CORBA::Object_ptr redirect_to); + +private: + + /// Prevent copying + ACE_UNIMPLEMENTED_FUNC (TAO_LB_Redirect_Table (const TAO_LB_Redirect_Table &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_LB_Redirect_Table &)) + +private: + + /// The implementation. + Table table_; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_REDIRECT_TABLE_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.cpp b/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.cpp new file mode 100644 index 00000000000..7b4040585b5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.cpp @@ -0,0 +1,21 @@ +// -*- C++ -*- + +#include "LB_ReplicaInfo.h" + +ACE_RCSID (LoadBalancing, + LB_ReplicaInfo, + "$Id$") + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Node<TAO_LB_ReplicaInfo *>; +template class ACE_Unbounded_Set<TAO_LB_ReplicaInfo *>; +template class ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *>; + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Node<TAO_LB_ReplicaInfo *> +#pragma instantiate ACE_Unbounded_Set<TAO_LB_ReplicaInfo *> +#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.h b/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.h new file mode 100644 index 00000000000..26ba0b5f5ff --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ReplicaInfo.h @@ -0,0 +1,59 @@ +// -*- C++ -*- + +//======================================================================= +/** + * @file LB_ReplicaInfo.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//======================================================================= + + +#ifndef TAO_LB_REPLICA_INFO_H +#define TAO_LB_REPLICA_INFO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +#include "orbsvcs/LoadBalancingC.h" + +#include "LB_Replica_Set.h" + +class TAO_LB_ReplicaInfo; +typedef ACE_Unbounded_Set<TAO_LB_ReplicaInfo *> TAO_LB_ReplicaInfoSet; +typedef ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *> TAO_LB_ReplicaInfoSetIterator; + + +/** + * @class TAO_LB_ReplicaInfo + * + * @brief Class that contains all replica-specific information. + */ +class TAO_LB_ReplicaInfo +{ +public: + + /// Reference to the replica. + CORBA::Object_var replica; + + /// FactoryInfo used when creating the replica. + LoadBalancing::FactoryInfo factory_info; + + /// FactoryCreationId assigned to this replica. This + /// FactoryCreationId_var will contain a zero pointer if the replica + /// was not created using a GenericFactory. + LoadBalancing::GenericFactory::FactoryCreationId_var factory_creation_id; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_INFO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing.idl b/TAO/orbsvcs/orbsvcs/LoadBalancing.idl index 70362f547ac..efac122abad 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing.idl +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing.idl @@ -18,6 +18,7 @@ #ifndef TAO_LOADBALANCING_IDL #define TAO_LOADBALANCING_IDL +#include "tao/PortableInterceptor.pidl" #include "CosNaming.idl" #include "orb.idl" @@ -27,7 +28,7 @@ * @class LoadBalancing * * @brief This module defines the interfaces and data types used in - * TAO's Load Balancing service. + * TAO's Load Balancing service. * @par * TAO's Load Balancer manages distribution of requests to replicas of * a given Object in an effort to ensure that the applications/hosts @@ -52,6 +53,7 @@ module LoadBalancing /// Specification of Common Types and Exceptions for ReplicationManager interface GenericFactory; interface LoadNotifier; + interface LoadMonitor; typedef unsigned long long ObjectGroupId; typedef unsigned long ObjectGroupRefVersion; @@ -168,7 +170,7 @@ module LoadBalancing }; /// Specification of ObjectGroupManager Interface which - /// ReplicationManager Inherits + /// ReplicationManager Inherits interface ObjectGroupManager { ObjectGroup create_member (in ObjectGroup object_group, in Location the_location, @@ -251,6 +253,23 @@ module LoadBalancing }; + /// Interface that all load monitors must implement. + interface LoadMonitor + { + /// Return the current load at the location the load monitor + /// resides. + readonly attribute LoadList current_load; + + /// Force redirection of requests for targets with the given + /// RepositoryId to the target pointed to by the given object + /// reference. + void register_redirect (in string type_id, + in Object redirect_to); + + /// Remove the redirect for targets of the given RepositoryId. + void remove_redirect (in string type_id); + }; + }; #pragma prefix "" diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.cpp index 753de0ee129..4a14567477f 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.cpp +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.cpp @@ -1,6 +1,8 @@ // -*- C++ -*- #include "LB_GenericFactory.h" +#include "LB_ReplicaInfo.h" + ACE_RCSID (LoadBalancing, LB_GenericFactory, @@ -141,39 +143,44 @@ TAO_LB_GenericFactory::delete_object ( if (this->object_group_map_.find (fcid, object_group) == -1) ACE_THROW (LoadBalancing::ObjectNotFound ()); - TAO_LB_Replica_Map *replica_map = object_group->replica_map; + TAO_LB_ReplicaInfo_Set &replica_infos = object_group->replica_infos; - for (TAO_LB_Replica_Map::Table::iterator i = replica_map->begin (); - i != replica_map->end (); - ++i) - { - TAO_LB_Replica_Map_Entry *replica = (*i).ext_id_; + { + ACE_GUARD (TAO_SYNCH_MUTEX, guard, object_group->lock); + for (TAO_LB_ReplicaInfoSetIterator i = replica_infos.begin (); + i != replica_infos.end (); + ++i) + { + TAO_LB_ReplicaInfo *replica_info = (*i).ext_id_; - LoadBalancing::GenericFactory_ptr factory = - replica->factory.in (); + LoadBalancing::GenericFactory_ptr factory = + replica_info->factory_info.the_factory.in (); - if (!CORBA::is_nil (factory)) - { - LoadBalancing::GenericFactory::FactoryCreationId - &replica_fcid = replica->factory_creation_id; + // If the factory reference is not nil, then the replica + // was created using a GenericFactory. Make sure that + // factory deletes it. + if (!CORBA::is_nil (factory)) + { + LoadBalancing::GenericFactory::FactoryCreationId + &replica_fcid = replica_info->factory_creation_id; - factory->delete_object (replica_fcid.in, ACE_TRY_ENV); - ACE_CHECK; - } + factory->delete_object (replica_fcid.in (), ACE_TRY_ENV); + ACE_CHECK; + } - - (void) replica_map->unbind (&(*i)); + (void) replica_info->unbind (&(*i)); - delete replica_map; - } + delete replica_info; + } + } // Now delete the ObjectGroup from the set of ObjectGroups. this->object_group_map_.unbind (fcid); delete object_group; } - - ACE_THROW (LoadBalancing::ObjectNotFound ()); + else + ACE_THROW (LoadBalancing::ObjectNotFound ()); } void @@ -184,7 +191,7 @@ TAO_LB_GenericFactory::populate_object_group ( for (CORBA::ULong j = 0; j < factory_infos_count; ++j) { // The FactoryInfo::the_location member was used when - // determining which FactoryInfo + // determining which FactoryInfo // member? // @@ It looks like it is only used when the application // control membership style is used. The application @@ -270,7 +277,7 @@ TAO_LB_GenericFactory::populate_object_group ( } // No longer need to protect the allocated Replica_Map. - safe_replica_entry.release (); + safe_replica_info.release (); } } diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.h index 0ed484b8656..811d5974fbe 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.h +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_GenericFactory.h @@ -35,8 +35,12 @@ class TAO_LB_ObjectGroup_Map; /** * @class TAO_LB_GenericFactory * - * @brief + * @brief LoadBalancing::GenericFactory implementation used by the + * load balancer when creating object groups. * + * This GenericFactory creates an object group reference for given set + * of replicas. Those replicas will be created by this GenericFactory + * if the "infrastructure-controlled" membership style is configured. */ class TAO_LB_GenericFactory : public virtual LoadBalancing::GenericFactory diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h index 3de656e0788..07843e8f37e 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h @@ -25,7 +25,7 @@ #include "ace/Hash_Map_Manager_T.h" #include "orbsvcs/LoadBalancingC.h" -#include "LB_Replica_Set.h" +#include "LB_ReplicaInfo_Set.h" /** @@ -37,13 +37,12 @@ */ class TAO_LB_ObjectGroup_Map { - public: /** * @class Map_Entry * - * @brief Value field of the replica map. + * @brief Value field of the ObjectGroup map. * * Mapping from and to all of the following fields: * @param object_group, @param factory_creation_id, @param factory, @@ -57,11 +56,14 @@ public: CORBA::String_var type_id; /// Reference to the ObjectGroup. - TAO_LoadBalancing::ObjectGroup_var object_group; + LoadBalancing::ObjectGroup_var object_group; /// Unbounded set containing replica references and all related /// information for each replica. TAO_LB_ReplicaInfo_Set replica_infos; + + /// Lock used to synchronize access to the ReplicaInfo set. + TAO_SYNCH_MUTEX lock; }; /// FactoryCreationId hash map. A FactoryCreationId is represented diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.cpp new file mode 100644 index 00000000000..99604af4fa7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.cpp @@ -0,0 +1,90 @@ +// -*- C++ -*- + +#include "LB_RPMS_Monitor.h" + + +ACE_RCSID (LoadBalancing, + LB_RPMS_Monitor, + "$Id$") + +TAO_LB_RPMS_Monitor::TAO_LB_RPMS_Monitor (void) +{ +} + +void +TAO_LB_RPMS_Monitor::init (CORBA::Environment &ACE_TRY_ENV) +{ + // Possibly no CORBA exceptions instantiated yet so don't attempt + // to throw one if allocation fails. + + TAO_LB_RPMS_Monitor_Interceptor *& interceptor = + this->interceptor_.out (); + + ACE_NEW (interceptor, + TAO_LB_RPMS_Monitor_Interceptor (this->object_group_.in ())); + + TAO_LB_RPMS_Monitor_ORBInitializer *initializer = 0; + ACE_NEW (temp_initializer, + TAO_LB_RPMS_Monitor_ORBInitializer (this->interceptor_.in ())); + + PortableInterceptor::ORBInitializer_var orb_initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (initializer.in (), + ACE_TRY_ENV); + ACE_CHECK; +} + +LoadBalancing::LoadList * +TAO_LB_RPMS_Monitor::current_load (CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Construct the LoadList here instead of inside the interceptor to + // maximize throughput in a multithreaded server replica by + // preventing two allocations from being added to the critical path + // of the client request. + // + // This optimization won't make a difference on single-threaded + // server replicas. + + LoadBalancing::LoadList *tmp_loads = 0; + ACE_NEW_THROW_EX (LoadBalancing::LoadList, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (0); + + LoadBalancing::LoadList_var loads = tmps_loads; + + loads->length (1); + + // The LoadId should be unique within the location this monitor + // resides. + loads[0].identifier = 0; // @todo Use a symbolic constant instead. + + loads[0].value = this->interceptor_->current_load (); + + return loads._retn (); +} + +void +TAO_LB_RPMS_Monitor::register_redirect (const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->interceptor_.register_redirect (type_id, + redirect_to, + ACE_TRY_ENV); +} + +void +TAO_LB_RPMS_Monitor::remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->interceptor_.remove_redirect (type_id, + ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.h new file mode 100644 index 00000000000..31f6a2705e6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor.h @@ -0,0 +1,88 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_RPMS_Monitor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_RPMS_MONITOR_H +#define TAO_LB_RPMS_MONITOR_H + +#include "ace/pre.h" + +#include "LoadBalancing_export.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/LoadBalancingS.h" + +#include "LB_RPMS_Monitor_Interceptor.h" + + +/** + * @class TAO_LB_RPMS_Monitor + * + * @brief LoadMonitor implementation that returns monitor the number + * of requests per second a given location receives. + * + * Since interceptors are locality-constrained, the Load Balancer + * actually makes feedback and control invocations methods through + * this LoadMonitor exposed by this LoadMonitor. This LoadMonitor + * basically delegates all of its work on to its underlying + * ServerRequestInterceptor. + */ +class TAO_LoadBalancing_Export TAO_LB_RPMS_Monitor + : public virtual POA_LoadBalancing::LoadMonitor +{ +public: + + /// Constructor + TAO_LB_RPMS_Monitor (void); + + /** + * @name LoadBalancing::LoadMonitor Methods + */ + //@{ + + /// Return the number of requests per second arriving at the + /// location this load monitor resides. + virtual LoadBalancing::LoadList *current_load ( + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Force redirection of requests for targets with the given + /// RepositoryId to the target pointed to by the given object + /// reference. + virtual void register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove the redirect for targets of the given RepositoryId. + virtual void remove_redirect ( + const char *type_id, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + +private: + + /// Interceptor responsible for keeping track of the number of + /// requests arriving per second. + TAO_LB_RPMS_Monitor_Interceptor_var interceptor_; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_RPMS_MONITOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.cpp new file mode 100644 index 00000000000..c8c9d5f2af7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.cpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +#include "LB_RPMS_Monitor_Interceptor.h" + +ACE_RCSID (LoadBalancing, + LB_RPMS_Monitor_Interceptor, + "$Id$") + + +#if defined (__ACE_INLINE__) +# include "LB_RPMS_Monitor_Interceptor.inl" +#endif /* __ACE_INLINE__ */ + + +TAO_LB_RPMS_Monitor_Interceptor::TAO_LB_RPMS_Monitor_Interceptor ( + CORBA::Object_ptr object_group) + : lock_ (), + redirect_table_ (), + request_count_ (0), + interval_start_ (ACE_OS::gettimeofday ()), + object_group_ () +{ +} + +char * +TAO_LB_RPMS_Monitor_Interceptor::name (TAO_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // @todo It might be necessary to use an anonymous interceptor, + // i.e. an interceptor whose name is the empty string ("") in + // case multiple interceptors of this type are registered with + // an ORB. + return CORBA::string_dup ("TAO_LB_RPMS_Monitor_Interceptor"); +} + +void +TAO_LB_RPMS_Monitor_Interceptor::destroy (TAO_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->redirect_table_.destroy (); +} + +void +TAO_LB_RPMS_Monitor_Interceptor::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + TAO_ENV_ARG_DEFN; + + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + ++this->request_count_; + + // If required to do so by the load balancer, redirect all + // requests back to the target corresponding to the RepositoryId in + // redirect table. + this->redirect_table_.find_redirect (ri, + ACE_TRY_ENV); + ACE_CHECK; +} + +void +TAO_LB_RPMS_Monitor_Interceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +TAO_LB_RPMS_Monitor_Interceptor::send_other ( + PortableInterceptor::ServerRequestInfo_ptr + TAO_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.h new file mode 100644 index 00000000000..cb0a7ccb247 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.h @@ -0,0 +1,159 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_RPMS_Monitor_Interceptor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_RPMS_MONITOR_INTERCEPTOR_H +#define TAO_LB_RPMS_MONITOR_INTERCEPTOR_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + +#includ "ace/Sync.h" + +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" + +/** + * @class TAO_LB_RPMS_Monitor_Interceptor + * + * @brief ServerRequestInterceptor that provides feedback and + * control. + * + * This ServerRequestInterceptor is used to count the number of + * requests per millisecond that are arriving at the location this + * interceptor resides. + */ +class TAO_LB_RPMS_Monitor_Interceptor + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual TAO_Local_RefCounted_Object +{ +public: + + /// Constructor + TAO_LB_RPMS_Monitor (void); + + /** + * @name Methods Required by the ServerRequestInterceptor + * Interface + * + * These are methods that must be implemented since they are pure + * virtual in the abstract base class. They are the canonical + * methods required for all server request interceptors. + */ + //@{ + + virtual char * name (TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy (TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// The bulk of the work this interceptor implementations performs + /// is in this interception point. + virtual void receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + TAO_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + //@} + + /** + * @name Feedback and control methods. + * + * Methods that indirectly provide feedback and control to the load + * balancer via the load monitor. + */ + //@{ + + /// Return the current average load (requests per second). + CORBA::Float current_load (void) const; + + /// Force redirection of requests for targets with the given + /// RepositoryId to the target pointed to by the given object + /// reference. + void register_redirect (const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV); + + /// Remove the redirect for targets of the given RepositoryId. + void remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV); + + //@} + +public: + + /// This template is actually instantiated in + /// `tao/Object_Ref_Table.cpp'. + typedef ACE_Hash_Map_Manager_Ex<const char *, CORBA::Object_ptr, ACE_Hash<const char *>, ACE_Equal_To<const char *>, ACE_Null_Mutex> Table; + +private: + + /// Lock that forces access request count to be modified/accessed + /// atomically. + TAO_SYNCH_MUTEX lock_; + + /// Flag that if set true will cause this interceptor to redirect + /// all requests back to the load balancer. + CORBA::Boolean redirect_requests_; + + /// The number of requests received at the location this interceptor + /// resides in the current measurement interval. + CORBA::ULong request_count_; + + // The start of the current measurement interval. + ACE_Time_Value interval_start_; + + /// Reference to the Load Balancer. + LoadBalancing::ReplicationManager_var lb_; + + + +}; + + +#if defined (__ACE_INLINE__) +# include "LB_RPMS_Monitor_Interceptor.inl" +#endif /* __ACE_INLINE__ */ + + +#include "ace/post.h" + +#endif /* TAO_LB_RPMS_MONITOR_INTERCEPTOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.inl new file mode 100644 index 00000000000..4cd431f4f15 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RPMS_Monitor_Interceptor.inl @@ -0,0 +1,45 @@ +// -*- C++ -*- + +ACE_INLINE CORBA::Float +TAO_LB_RPMS_Monitor_Interceptor::current_load (void) const +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + ACE_Time_Value elapsed_time = + ACE_OS::gettimeofday () - this->interval_start_; + + this->interval_start_ = ACE_OS::gettimeofday (); + + CORBA::Float load = + ACE_static_cast (CORBA::Float, + this->request_count_) / elapsed_time.msec (); + + this->request_count_ = 0; + this->interval_start_ = ACE_OS::gettimeofday (); + + return load; +} + +ACE_INLINE void +TAO_LB_RPMS_Monitor_Interceptor::register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->redirect_table_.register_redirect (type_id, + redirect_to, + ACE_TRY_ENV); +} + +ACE_INLINE void +TAO_LB_RPMS_Monitor_Interceptor::remove_redirect ( + const char *type_id, + CORBA::Environment &ACE_TRY_ENV) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_); + + this->redirect_table_.remove_redirect (type_id, + ACE_TRY_ENV); +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.cpp new file mode 100644 index 00000000000..9a6b33d519a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.cpp @@ -0,0 +1,180 @@ +// -*- C++ -*- + +#include "LB_Redirect_Table.h" +#include "Object.h" +#include "Exception.h" +#include "Environment.h" +#include "CORBA_String.h" +#include "debug.h" + +ACE_RCSID (LoadBalancing, + LB_Redirect_Table, + "$Id$") + +// **************************************************************** + +TAO_LB_Redirect_Table::TAO_LB_Redirect_Table (void) + : table_ () +{ +} + +TAO_LB_Redirect_Table::~TAO_LB_Redirect_Table (void) +{ + // Must explicitly call destroy() in the destructor since not all + // applications will invoke ORB::shutdown() or ORB::destroy(). + this->destroy (); +} + +void +TAO_LB_Redirect_Table::register_redirect ( + const char *type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV) +{ + // The RepositoryId should never be zero since it is not possible to + // send a NULL string as an "in" argument. + if (ACE_OS_String::strlen (id) == 0) + ACE_THROW (CORBA::BAD_PARAM ()); + + if (CORBA::is_nil (obj)) + ACE_THROW (CORBA::BAD_PARAM ()); + + int result = this->bind (type_id, redirect_to); + + if (result == 1) + { + if (TAO_debug_level > 1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) LB_Redirect_Table::register_redirect:\n" + " Could not register duplicate object <%s> with " + "the LB_Redirect_Table\n", + type_id)); + + ACE_THROW (CORBA::INV_OBJREF ()); + } + + if (result == -1) + { + if (TAO_debug_level > 1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) LB_Redirect_Table::register_redirect:\n" + " Could not register redirect object <%s> with " + "the LB_Redirect_Table\n", + type_id)); + + ACE_THROW (CORBA::INTERNAL ()); + } +} + +void +TAO_LB_Redirect_Table::find_redirect ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::Environment &ACE_TRY_ENV) +{ + // This could become very slow if there are many type of targets + // being redirected since we're doing a linear search using string + // comparisons. + // + // We do things this way to avoid the memory allocation that would + // occur if we were to just use the + // ServerRequestInfo::target_most_derived_interface() method. At + // some point, there is a threshold reached where the cost of the + // iteration through the redirect table is more expensive than the + // allocation incurred by calling + // ServerRequestInfo::target_most_derived_interface(). That + // threshold is approached as the number of redirects in the table + // becomes "large." For now, we optimize for the common case and + // assume that only a few types of targets (i.e. objects/servants + // with different RepositoryIds) exist at the current location. + // + // Note that if no redirects are registered, then this method + // basically becomes a no-op. + + for (Table::iterator i = this->table_.begin (); + i != this->table_.end (); + ++i) + { + // Compare the target's RepositoryId with the registered + // redirects. + CORBA::Boolean matched = + ri->target_is_a ((*i).ext_id_, ACE_TRY_ENV); + ACE_CHECK_RETURN (0); + + if (matched) + ACE_THROW (PortableInterceptor::ForwardRequest ( + (*i).int_id_, + 0 /* non-permanent forward */)); + } +} + +int +TAO_LB_Redirect_Table::remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV) +{ + Table::ENTRY *entry = 0; + + int result = this->table_.find (type_id, entry); + + if (result == 0) + { + // Deallocate the external ID and obtain the ORB core pointer + // before unbinding the entry since the entry is deallocated + // during the call to unbind(). + CORBA::string_free (ACE_const_cast (char *, entry->ext_id_)); + CORBA::Object_ptr redirect = entry->int_id_; + + result = this->table_.unbind (entry); + + if (result != 0) + return result; + + CORBA::release (redirect); + } + + return result; +} + +void +TAO_LB_Redirect_Table::destroy (void) +{ + for (Table::iterator i = this->table_.begin (); + i != this->table_.end (); + ++i) + { + // Deallocate the id. + CORBA::string_free (ACE_const_cast (char *, (*i).ext_id_)); + + // Release the Object. + CORBA::release ((*i).int_id_); + } + + this->table_.unbind_all (); +} + +int +TAO_LB_Redirect_Table::bind (const char *id, + CORBA::Object_ptr obj) +{ + // Make sure that the supplied Object reference is valid, + // i.e. not nil. + if (id == 0 || CORBA::is_nil (obj)) + { + errno = EINVAL; + return -1; + }; + + CORBA::String_var type_id = CORBA::string_dup (id); + CORBA::Object_var redirect = CORBA::Object::_duplicate (obj); + + int result = this->table_.bind (type_id.in (), + redirect.in ()); + + if (result == 0) + { + // Transfer ownership to the Object Table. + (void) type_id._retn (); + (void) redirect._retn (); + } + + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.h new file mode 100644 index 00000000000..0b3d6d09161 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Redirect_Table.h @@ -0,0 +1,100 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file LB_Redirect_Table.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + + +#ifndef TAO_LB_REDIRECT_TABLE_H +#define TAO_LB_REDIRECT_TABLE_H + +#include "ace/pre.h" + +#include "corbafwd.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Functor.h" + + +/** + * @class TAO_LB_Redirect_Table + * + * @brief Maintain a table of "redirects" corresponding to a target + * with the given RepositoryId. + * + * If a table entry for the given RepositoryId exists, then the load + * monitor will redirect the client request to the target pointed to + * by the object reference in that entry. + * + * It is necessary to maintain a redirect table since the load + * balancer determines which object group to select a replica from by + * examining the target's object ID. As such a request cannot simply + * be forwarded back to the load balancer without knowing what its + * intended target (i.e. object group) is. This table keeps track of + * the object group reference to which a replica of a given type + * belongs. + */ +class TAO_LB_Redirect_Table +{ +public: + + typedef ACE_Hash_Map_Manager_Ex<const char *, CORBA::Object_ptr, ACE_Hash<const char *>, ACE_Equal_To<const char *>, ACE_Null_Mutex> Table; + + /// Constructor + TAO_LB_Redirect_Table (void); + + /// Destructor + ~TAO_LB_Redirect_Table (void); + + /// Register an object reference with the table, and map the given + /// ID to it. + void register_redirect (const char * type_id, + CORBA::Object_ptr redirect_to, + CORBA::Environment &ACE_TRY_ENV); + + /// Remove the redirect associated with the given RepositoryId. + void remove_redirect (const char *type_id, + CORBA::Environment &ACE_TRY_ENV); + + /// Check if a redirect exists for the current target. If so, then + /// perform the request redirection by throwing a + /// PortableInterceptor::ForwardRequest exception. + void find_redirect (PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::Environment &ACE_TRY_ENV); + + /// Reclaim the resources held by this table (deallocate strings, + /// release object references, etc). + void destroy (void); + +private: + + /// Helper method that binds the redirect to the given RepositoryId. + int bind (const char *type_id, CORBA::Object_ptr redirect_to); + +private: + + /// Prevent copying + ACE_UNIMPLEMENTED_FUNC (TAO_LB_Redirect_Table (const TAO_LB_Redirect_Table &)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_LB_Redirect_Table &)) + +private: + + /// The implementation. + Table table_; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_REDIRECT_TABLE_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.cpp new file mode 100644 index 00000000000..7b4040585b5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.cpp @@ -0,0 +1,21 @@ +// -*- C++ -*- + +#include "LB_ReplicaInfo.h" + +ACE_RCSID (LoadBalancing, + LB_ReplicaInfo, + "$Id$") + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Node<TAO_LB_ReplicaInfo *>; +template class ACE_Unbounded_Set<TAO_LB_ReplicaInfo *>; +template class ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *>; + +#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Node<TAO_LB_ReplicaInfo *> +#pragma instantiate ACE_Unbounded_Set<TAO_LB_ReplicaInfo *> +#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.h new file mode 100644 index 00000000000..26ba0b5f5ff --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ReplicaInfo.h @@ -0,0 +1,59 @@ +// -*- C++ -*- + +//======================================================================= +/** + * @file LB_ReplicaInfo.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//======================================================================= + + +#ifndef TAO_LB_REPLICA_INFO_H +#define TAO_LB_REPLICA_INFO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +#include "orbsvcs/LoadBalancingC.h" + +#include "LB_Replica_Set.h" + +class TAO_LB_ReplicaInfo; +typedef ACE_Unbounded_Set<TAO_LB_ReplicaInfo *> TAO_LB_ReplicaInfoSet; +typedef ACE_Unbounded_Set_Iterator<TAO_LB_ReplicaInfo *> TAO_LB_ReplicaInfoSetIterator; + + +/** + * @class TAO_LB_ReplicaInfo + * + * @brief Class that contains all replica-specific information. + */ +class TAO_LB_ReplicaInfo +{ +public: + + /// Reference to the replica. + CORBA::Object_var replica; + + /// FactoryInfo used when creating the replica. + LoadBalancing::FactoryInfo factory_info; + + /// FactoryCreationId assigned to this replica. This + /// FactoryCreationId_var will contain a zero pointer if the replica + /// was not created using a GenericFactory. + LoadBalancing::GenericFactory::FactoryCreationId_var factory_creation_id; + +}; + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_INFO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp index 3102244a876..4cba2d3c82b 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp @@ -36,7 +36,7 @@ TAO_LoadBalancing_ReplicationManager_i::register_load_notifier ( CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC ((CORBA::SystemException)) { - ACE_THROW (CORBA::NO_IMPLEMENT()); + ACE_THROW (CORBA::NO_IMPLEMENT ()); } LoadBalancing::LoadNotifier_ptr @@ -360,6 +360,17 @@ TAO_LoadBalancing_ReplicationManager_i::delete_object ( ACE_TRY_ENV); } +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::replica ( + const PortableServer::ObjectId &oid, + CORBA::Environment &ACE_TRY_ENV) +{ + // Convert the ObjectId to the hash map key. + CORBA::String_var stroid = PortableServer::ObjectId_to_string (oid); + + int tmp = ACE_OS::atoi (stroid.in ()); +} + int TAO_LoadBalancing_ReplicationManager_i::init ( PortableServer::POA_ptr root_poa) diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h index 21ea01a1ebc..129bf2ddedd 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h @@ -2,7 +2,7 @@ //============================================================================= /** - * @file ReplicaLocator.h + * @file LoadBalancingI.h * * $Id$ * diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/NOTES b/TAO/orbsvcs/orbsvcs/LoadBalancing/NOTES index 2eb4428ec19..8a45993a019 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/NOTES +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/NOTES @@ -10,7 +10,7 @@ ReplicaLocator::pre_invoke () LoadAnalyzer.get_replica ( ObjectId ) { ObjectId_Replica_Map.find (ObjectId, Location_Replica_Map); - + Location_Replica_Map (select replica from it); } @@ -109,4 +109,3 @@ if (!CORBA::is_nil (replica_map_entry->factory_info.the_factory.in ()) delete replica_map_entry; // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- - diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp index 3102244a876..4cba2d3c82b 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp +++ b/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp @@ -36,7 +36,7 @@ TAO_LoadBalancing_ReplicationManager_i::register_load_notifier ( CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC ((CORBA::SystemException)) { - ACE_THROW (CORBA::NO_IMPLEMENT()); + ACE_THROW (CORBA::NO_IMPLEMENT ()); } LoadBalancing::LoadNotifier_ptr @@ -360,6 +360,17 @@ TAO_LoadBalancing_ReplicationManager_i::delete_object ( ACE_TRY_ENV); } +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::replica ( + const PortableServer::ObjectId &oid, + CORBA::Environment &ACE_TRY_ENV) +{ + // Convert the ObjectId to the hash map key. + CORBA::String_var stroid = PortableServer::ObjectId_to_string (oid); + + int tmp = ACE_OS::atoi (stroid.in ()); +} + int TAO_LoadBalancing_ReplicationManager_i::init ( PortableServer::POA_ptr root_poa) diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancingI.h b/TAO/orbsvcs/orbsvcs/LoadBalancingI.h index 21ea01a1ebc..129bf2ddedd 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancingI.h +++ b/TAO/orbsvcs/orbsvcs/LoadBalancingI.h @@ -2,7 +2,7 @@ //============================================================================= /** - * @file ReplicaLocator.h + * @file LoadBalancingI.h * * $Id$ * diff --git a/TAO/orbsvcs/orbsvcs/NOTES b/TAO/orbsvcs/orbsvcs/NOTES index 2eb4428ec19..8a45993a019 100644 --- a/TAO/orbsvcs/orbsvcs/NOTES +++ b/TAO/orbsvcs/orbsvcs/NOTES @@ -10,7 +10,7 @@ ReplicaLocator::pre_invoke () LoadAnalyzer.get_replica ( ObjectId ) { ObjectId_Replica_Map.find (ObjectId, Location_Replica_Map); - + Location_Replica_Map (select replica from it); } @@ -109,4 +109,3 @@ if (!CORBA::is_nil (replica_map_entry->factory_info.the_factory.in ()) delete replica_map_entry; // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- - |