📄 lb_leastloaded.cpp
字号:
}
}
ACE_CATCH (CosLoadBalancing::LocationNotFound, ex)
{
// No load available for the requested location. Try the
// next location.
}
ACE_ENDTRY;
ACE_CHECK;
}
}
PortableServer::POA_ptr
TAO_LB_LeastLoaded::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
{
return PortableServer::POA::_duplicate (this->poa_.in ());
}
CORBA::Boolean
TAO_LB_LeastLoaded::get_location (
CosLoadBalancing::LoadManager_ptr load_manager,
const PortableGroup::Locations & locations,
PortableGroup::Location & location
ACE_ENV_ARG_DECL)
{
CORBA::Float min_load = FLT_MAX; // Start out with the largest
// positive value.
CORBA::ULong location_index = 0;
CORBA::Boolean found_location = 0;
CORBA::Boolean found_load = 0;
const CORBA::ULong len = locations.length ();
// Iterate through the entire location list to find the least loaded
// of them.
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;
found_load = 1;
CosLoadBalancing::Load load;
this->push_loads (loc,
current_loads.in (),
load
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// ACE_DEBUG ((LM_DEBUG,
// "LOC = %u"
// "\tC = %d"
// "\treject = %f"
// "\tload = %f\n"
// "\tmin_load = %f\n",
// i,
// (this->reject_threshold_ == 0
// || load.value < this->reject_threshold_),
// this->reject_threshold_,
// load.value,
// min_load));
if ((this->reject_threshold_ == 0
|| load.value < this->reject_threshold_)
&& load.value < min_load)
{
// ACE_DEBUG ((LM_DEBUG,
// "**** LOAD == %f\n",
// load.value));
if (i > 0 && load.value != 0)
{
/*
percent difference =
(min_load - load.value) / load.value
== (min_load / load.value) - 1
The latter form is used to avoid a potential
arithmetic overflow problem, such as when
(min_load - load.value) > FLT_MAX, assuming that
either load.value is negative and min_load is
positive, or vice versa.
*/
const CORBA::Float percent_diff =
(min_load / load.value) - 1;
/*
A "thundering herd" phenomenon may occur when
location loads are basically the same (e.g. only
differ by a very small amount), where one object
group member ends up receiving the majority of
requests from different clients. In order to
prevent a single object group member from
receiving such request bursts, one of two equally
loaded locations is chosen at random. Thanks to
Carlos, Marina and Jody at ATD for coming up with
this solution to this form of the thundering herd
problem.
See the documentation for
TAO_LB::LL_DEFAULT_LOAD_PERCENT_DIFF_CUTOFF in
LB_LeastLoaded.h for additional information.
*/
if (percent_diff <= TAO_LB::LL_DEFAULT_LOAD_PERCENT_DIFF_CUTOFF)
{
// Prevent integer arithmetic overflow.
const CORBA::Float NUM_MEMBERS = 2;
// n == 0: Use previously selected location.
// n == 1: Use current location.
const CORBA::ULong n =
ACE_static_cast (CORBA::ULong,
NUM_MEMBERS * ACE_OS::rand ()
/ (RAND_MAX + 1.0));
ACE_ASSERT (n == 0 || n == 1);
if (n == 1)
{
min_load = load.value;
location_index = i;
found_location = 1;
// ACE_DEBUG ((LM_DEBUG,
// "** NEW MIN_LOAD == %f\n",
// min_load));
}
// if (n == 0)
// ACE_DEBUG ((LM_DEBUG, "^^^^^ PREVIOUS LOCATION\n"));
// else
// ACE_DEBUG ((LM_DEBUG, "^^^^^ CURRENT LOCATION\n"));
}
else
{
min_load = load.value;
location_index = i;
found_location = 1;
// ACE_DEBUG ((LM_DEBUG,
// "***** NEW MIN_LOAD == %f\n",
// min_load));
}
}
else
{
min_load = load.value;
location_index = i;
found_location = 1;
// ACE_DEBUG ((LM_DEBUG,
// "NEW MIN_LOAD == %f\n",
// min_load));
}
}
// ACE_DEBUG ((LM_DEBUG, "NEW MIN_LOAD == %f\n", min_load));
}
ACE_CATCH (CosLoadBalancing::LocationNotFound, ex)
{
// No load available for the requested location. Try the
// next location.
}
ACE_ENDTRY;
ACE_CHECK_RETURN (0);
}
// ACE_DEBUG ((LM_DEBUG,
// "FOUND_LOAD == %u\n"
// "FOUND_LOCATION == %u\n",
// found_load,
// found_location));
// If no loads were found, return without an exception to allow this
// strategy to select a member using an alternative method
// (e.g. random selection).
if (found_load)
{
if (found_location)
location = locations[location_index];
else if (this->reject_threshold_ != 0)
ACE_THROW_RETURN (CORBA::TRANSIENT (), 0);
// ACE_DEBUG ((LM_DEBUG, "LOCATION ID == %s\n", location[0].id.in ()));
}
// ACE_DEBUG ((LM_DEBUG, "LOCATED = %u\n", location_index));
return found_location;
}
void
TAO_LB_LeastLoaded::init (const PortableGroup::Properties & props
ACE_ENV_ARG_DECL)
{
CORBA::Float critical_threshold =
TAO_LB::LL_DEFAULT_CRITICAL_THRESHOLD;
CORBA::Float reject_threshold = TAO_LB::LL_DEFAULT_REJECT_THRESHOLD;
CORBA::Float tolerance = TAO_LB::LL_DEFAULT_TOLERANCE;
CORBA::Float dampening = TAO_LB::LL_DEFAULT_DAMPENING;
CORBA::Float per_balance_load = TAO_LB::LL_DEFAULT_PER_BALANCE_LOAD;
const PortableGroup::Property * ct = 0; // critical threshold property
const PortableGroup::Property * rt = 0; // reject threshold property
const CORBA::ULong len = props.length ();
for (CORBA::ULong i = 0; i < len; ++i)
{
const PortableGroup::Property & property = props[i];
if (ACE_OS::strcmp (property.nam[0].id.in (),
"org.omg.CosLoadBalancing.Strategy.LeastLoaded.CriticalThreshold") == 0)
{
this->extract_float_property (property,
critical_threshold
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
ct = &property;
}
else if (ACE_OS::strcmp (property.nam[0].id.in (),
"org.omg.CosLoadBalancing.Strategy.LeastLoaded.RejectThreshold") == 0)
{
this->extract_float_property (property,
reject_threshold
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
rt = &property;
}
else if (ACE_OS::strcmp (property.nam[0].id.in (),
"org.omg.CosLoadBalancing.Strategy.LeastLoaded.Tolerance") == 0)
{
this->extract_float_property (property,
tolerance
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Valid tolerance values are greater than or equal to one.
if (tolerance < 1)
ACE_THROW (PortableGroup::InvalidProperty (property.nam,
property.val));
}
else if (ACE_OS::strcmp (property.nam[0].id.in (),
"org.omg.CosLoadBalancing.Strategy.LeastLoaded.Dampening") == 0)
{
this->extract_float_property (property,
dampening
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Dampening range is [0,1).
if (dampening < 0 || dampening >= 1)
ACE_THROW (PortableGroup::InvalidProperty (property.nam,
property.val));
}
else if (ACE_OS::strcmp (property.nam[0].id.in (),
"org.omg.CosLoadBalancing.Strategy.LeastLoaded.PerBalanceLoad") == 0)
{
this->extract_float_property (property,
per_balance_load
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
}
if (critical_threshold != 0 && reject_threshold != 0
&& critical_threshold <= reject_threshold)
ACE_THROW (PortableGroup::InvalidProperty (ct->nam, ct->val));
this->properties_ = props;
this->critical_threshold_ = critical_threshold;
this->reject_threshold_ = reject_threshold;
this->tolerance_ = tolerance;
this->dampening_ = dampening;
this->per_balance_load_ = per_balance_load;
// ACE_DEBUG ((LM_DEBUG,
// "--------------------------------\n"
// "critical_threshold = %f\n"
// "reject_threshold = %f\n"
// "tolerance = %f\n"
// "dampening = %f\n"
// "per_balance_load = %f\n"
// "--------------------------------\n",
// critical_threshold,
// reject_threshold,
// tolerance,
// dampening,
// per_balance_load));
}
void
TAO_LB_LeastLoaded::extract_float_property (
const PortableGroup::Property & property,
CORBA::Float & value
ACE_ENV_ARG_DECL)
{
if (!(property.val >>= value))
ACE_THROW (PortableGroup::InvalidProperty (property.nam,
property.val));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -