📄 lb_leastloaded.cpp
字号:
#include "LB_LeastLoaded.h"
#include "LB_LoadMap.h"
#include "LB_Random.h"
#include "orbsvcs/PortableGroup/PG_conf.h"
#include "tao/debug.h"
#include "tao/ORB_Constants.h"
#include "ace/Null_Mutex.h"
ACE_RCSID (LoadBalancing,
LB_LeastLoaded,
"LB_LeastLoaded.cpp,v 1.14 2003/12/10 22:40:27 ossama Exp")
#if !defined (__ACE_INLINE__)
#include "LB_LeastLoaded.inl"
#endif /* defined INLINE */
TAO_LB_LeastLoaded::TAO_LB_LeastLoaded (PortableServer::POA_ptr poa)
: poa_ (PortableServer::POA::_duplicate (poa)),
load_map_ (0),
lock_ (0),
properties_ (),
critical_threshold_ (TAO_LB::LL_DEFAULT_CRITICAL_THRESHOLD),
reject_threshold_ (TAO_LB::LL_DEFAULT_REJECT_THRESHOLD),
tolerance_ (TAO_LB::LL_DEFAULT_TOLERANCE),
dampening_ (TAO_LB::LL_DEFAULT_DAMPENING),
per_balance_load_ (TAO_LB::LL_DEFAULT_DAMPENING)
{
// A load map that retains previous load values at a given location
// and lock are only needed if dampening is enabled, i.e. non-zero.
if (this->dampening_ != 0)
{
ACE_NEW (this->load_map_, TAO_LB_LoadMap (TAO_PG_MAX_LOCATIONS));
ACE_NEW (this->lock_, TAO_SYNCH_MUTEX);
}
// Initialize the random load balancing strategy.
TAO_LB_Random::init ();
}
TAO_LB_LeastLoaded::~TAO_LB_LeastLoaded (void)
{
delete this->load_map_;
delete this->lock_;
}
char *
TAO_LB_LeastLoaded::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
ACE_THROW_SPEC ((CORBA::SystemException))
{
return CORBA::string_dup ("LeastLoaded");
}
CosLoadBalancing::Properties *
TAO_LB_LeastLoaded::get_properties (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
CosLoadBalancing::Properties * props = 0;
ACE_NEW_THROW_EX (props,
CosLoadBalancing::Properties (this->properties_),
CORBA::NO_MEMORY (
CORBA::SystemException::_tao_minor_code (
TAO_DEFAULT_MINOR_CODE,
ENOMEM),
CORBA::COMPLETED_NO));
ACE_CHECK_RETURN (0);
return props;
}
void
TAO_LB_LeastLoaded::push_loads (
const PortableGroup::Location & the_location,
const CosLoadBalancing::LoadList & loads
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
// Only the first load is used by this load balancing strategy.
if (loads.length () == 0)
ACE_THROW (CORBA::BAD_PARAM ());
CosLoadBalancing::Load load; // Unused
this->push_loads (the_location,
loads,
load
ACE_ENV_ARG_PARAMETER);
}
void
TAO_LB_LeastLoaded::push_loads (
const PortableGroup::Location & the_location,
const CosLoadBalancing::LoadList & loads,
CosLoadBalancing::Load & load
ACE_ENV_ARG_DECL)
{
if (loads.length () == 0)
ACE_THROW (CORBA::BAD_PARAM ());
// Only the first load is used by this load balancing strategy.
const CosLoadBalancing::Load & new_load = loads[0];
if (this->load_map_ != 0)
{
ACE_GUARD (TAO_SYNCH_MUTEX, guard, *this->lock_);
TAO_LB_LoadMap::ENTRY * entry;
if (this->load_map_->find (the_location, entry) == 0)
{
CosLoadBalancing::Load & previous_load = entry->int_id_;
if (previous_load.id != new_load.id)
ACE_THROW (CORBA::BAD_PARAM ()); // Somebody switched
// LoadIds on us!
previous_load.value =
this->effective_load (previous_load.value, new_load.value);
load = previous_load;
}
else
{
const CosLoadBalancing::Load eff_load =
{
new_load.id,
this->effective_load (0, new_load.value)
};
if (this->load_map_->bind (the_location, eff_load) != 0)
{
if (TAO_debug_level > 0)
ACE_ERROR ((LM_ERROR,
"ERROR: TAO_LB_LeastLoaded - "
"Unable to push loads\n"));
ACE_THROW (CORBA::INTERNAL ());
}
load = eff_load;
}
}
else
{
load.id = new_load.id;
load.value = this->effective_load (0, new_load.value);
}
}
CosLoadBalancing::LoadList *
TAO_LB_LeastLoaded::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
const PortableGroup::Location & the_location
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
CosLoadBalancing::LocationNotFound))
{
if (CORBA::is_nil (load_manager))
ACE_THROW_RETURN (CORBA::BAD_PARAM (), 0);
CosLoadBalancing::LoadList_var loads =
load_manager->get_loads (the_location
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
this->push_loads (the_location,
loads.in (),
loads[0]
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
return loads._retn ();
}
CORBA::Object_ptr
TAO_LB_LeastLoaded::next_member (
PortableGroup::ObjectGroup_ptr object_group,
CosLoadBalancing::LoadManager_ptr load_manager
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableGroup::ObjectGroupNotFound,
PortableGroup::MemberNotFound))
{
if (CORBA::is_nil (load_manager))
ACE_THROW_RETURN (CORBA::BAD_PARAM (),
CORBA::Object::_nil ());
PortableGroup::Locations_var locations =
load_manager->locations_of_members (object_group
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (CORBA::Object::_nil ());
if (locations->length () == 0)
ACE_THROW_RETURN (CORBA::TRANSIENT (),
CORBA::Object::_nil ());
// @@ RACE CONDITION. OBJECT GROUP MEMBERSHIP MAY CHANGE AFTER
// RETRIEVING LOCATIONS! HOW DO WE HANDLE THAT?
PortableGroup::Location location;
CORBA::Boolean found_location =
this->get_location (load_manager,
locations.in (),
location
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (CORBA::Object::_nil ());
if (found_location)
{
// ACE_DEBUG ((LM_DEBUG,
// "RETURNING REFERENCE FOR LOCATION \"%s\"\n",
// location[0].id.in ()));
return load_manager->get_member_ref (object_group,
location
ACE_ENV_ARG_PARAMETER);
}
else
{
// No loads have been reported for any of the locations the
// object group members reside at. If no loads have been
// reported to the LoadManager, adaptive load balancing
// decisions cannot be made. Fall back on a non-adaptive
// strategy, such as the Random load balancing strategy,
// instead.
//
// @note The Random load balancing strategy is used since it is
// very lightweight and stateless.
return TAO_LB_Random::_tao_next_member (object_group,
load_manager,
locations.in ()
ACE_ENV_ARG_PARAMETER);
}
}
void
TAO_LB_LeastLoaded::analyze_loads (
PortableGroup::ObjectGroup_ptr object_group,
CosLoadBalancing::LoadManager_ptr load_manager
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
if (CORBA::is_nil (load_manager))
ACE_THROW (CORBA::BAD_PARAM ());
PortableGroup::Locations_var locations =
load_manager->locations_of_members (object_group
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (locations->length () == 0)
ACE_THROW (CORBA::TRANSIENT ());
const CORBA::ULong len = locations->length ();
// Iterate through the entire location list to determine which
// locations require load to be shed.
for (CORBA::ULong i = 0; i < len; ++i)
{
ACE_TRY
{
const PortableGroup::Location & loc = locations[i];
// Retrieve the load list for the location from the
// LoadManager and push it to this Strategy's load
// processor.
CosLoadBalancing::LoadList_var current_loads =
load_manager->get_loads (loc
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
CosLoadBalancing::Load load;
this->push_loads (loc,
current_loads.in (),
load
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// ACE_DEBUG ((LM_DEBUG,
// "EFFECTIVE_LOAD == %f\n"
// "CRITICAL == %f\n"
// "REJECT == %f\n"
// "DAMPENING == %f\n",
// load.value,
// this->critical_threshold_,
// this->reject_threshold_,
// this->dampening_));
// Perform load rebalancing only if the critical threshold
// was set.
if (this->critical_threshold_ != 0)
{
if (load.value > this->critical_threshold_)
{
// ACE_DEBUG ((LM_DEBUG,
// "%P --- ALERTING LOCATION %u\n",
// i));
// The location is overloaded. Perform load
// shedding by informing the LoadAlert object
// associated with the member at that location it
// should redirect client requests back to the
// LoadManager.
load_manager->enable_alert (loc
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
else
{
// The location is not overloaded. Disable load
// shedding at given location.
load_manager->disable_alert (loc
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -