summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp110
1 files changed, 100 insertions, 10 deletions
diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
index 37f458dd722..9252ffaf438 100644
--- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
+++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
@@ -1,5 +1,3 @@
-// -*- C++ -*-
-
#include "LB_LeastLoaded.h"
#include "LB_LoadMap.h"
#include "LB_Random.h"
@@ -211,6 +209,10 @@ TAO_LB_LeastLoaded::next_member (
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);
@@ -340,7 +342,7 @@ TAO_LB_LeastLoaded::get_location (
ACE_ENV_ARG_DECL)
{
CORBA::Float min_load = FLT_MAX; // Start out with the largest
- // possible.
+ // positive value.
CORBA::ULong location_index = 0;
CORBA::Boolean found_location = 0;
@@ -374,14 +376,16 @@ TAO_LB_LeastLoaded::get_location (
// ACE_DEBUG ((LM_DEBUG,
// "LOC = %u"
-// "\tCOND = %d"
+// "\tC = %d"
// "\treject = %f"
-// "\tload = %f\n",
+// "\tload = %f\n"
+// "\tmin_load = %f\n",
// i,
// (this->reject_threshold_ == 0
// || load.value < this->reject_threshold_),
// this->reject_threshold_,
-// load.value));
+// load.value,
+// min_load));
if ((this->reject_threshold_ == 0
|| load.value < this->reject_threshold_)
@@ -391,10 +395,94 @@ TAO_LB_LeastLoaded::get_location (
// "**** LOAD == %f\n",
// load.value));
- min_load = load.value;
- location_index = i;
- found_location = 1;
+ 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)
{
@@ -407,7 +495,7 @@ TAO_LB_LeastLoaded::get_location (
// ACE_DEBUG ((LM_DEBUG,
// "FOUND_LOAD == %u\n"
-// "FOUND_LOCATION = %u\n",
+// "FOUND_LOCATION == %u\n",
// found_load,
// found_location));
@@ -420,6 +508,8 @@ TAO_LB_LeastLoaded::get_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));