summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp406
1 files changed, 145 insertions, 261 deletions
diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp
index 367432d7337..d7c694f21a6 100644
--- a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp
+++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Invocation_Endpoint_Selectors.cpp
@@ -2,12 +2,13 @@
#include "FT_Invocation_Endpoint_Selectors.h"
-#include "tao/Invocation.h"
+#include "tao/Profile_Transport_Resolver.h"
#include "tao/Stub.h"
#include "tao/Profile.h"
#include "tao/Endpoint.h"
#include "tao/Base_Transport_Property.h"
#include "tao/debug.h"
+#include "ace/Log_Msg.h"
#if !defined (__ACE_INLINE__)
#include "tao/Invocation_Endpoint_Selectors.i"
@@ -18,9 +19,7 @@ ACE_RCSID (FaultTolerance,
"$Id$")
TAO_FT_Invocation_Endpoint_Selector::TAO_FT_Invocation_Endpoint_Selector (void)
- : TAO_Default_Endpoint_Selector (),
- is_primary_alive_ (1),
- is_rewound_ (0)
+ : TAO_Default_Endpoint_Selector ()
{
}
@@ -30,278 +29,192 @@ TAO_FT_Invocation_Endpoint_Selector::~TAO_FT_Invocation_Endpoint_Selector (void)
void
TAO_FT_Invocation_Endpoint_Selector::select_endpoint (
- TAO_GIOP_Invocation *invocation
- ACE_ENV_ARG_DECL)
+ TAO::Profile_Transport_Resolver *r,
+ ACE_Time_Value *val
+ ACE_ENV_ARG_DECL)
{
+ bool retval =
+ this->select_primary (r,
+ val
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
- int retval = this->select_endpoint_i (invocation
- ACE_ENV_ARG_PARAMETER);
+ if (retval)
+ return;
+
+ retval =
+ this->select_secondary (r,
+ val
+ ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
- if (retval == 0)
+ if (retval == false)
{
- if (TAO_debug_level > 6)
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO-FT - Primary doesnt exist.",
- "Falling back on the default selection routines \n"));
-
- TAO_Default_Endpoint_Selector::select_endpoint (invocation
- ACE_ENV_ARG_PARAMETER);
- ACE_CHECK;
+ // If we get here, we completely failed to find an endpoint selector
+ // that we know how to use, so throw an exception.
+ ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
+ CORBA::COMPLETED_NO));
}
return;
}
-// @@ RTCORBA_Subsetting - next should be deprecated...
-void
-TAO_FT_Invocation_Endpoint_Selector::next (TAO_GIOP_Invocation *
- ACE_ENV_ARG_DECL_NOT_USED)
-{
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("This method is DEPRECATED!\n")));
- // if (invocation->stub_->next_profile_retry () == 0)
- // ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
- // CORBA::COMPLETED_NO));
-}
-
-void
-TAO_FT_Invocation_Endpoint_Selector::forward (TAO_GIOP_Invocation
- *invocation,
- const TAO_MProfile &mprofile
- ACE_ENV_ARG_DECL)
-{
- invocation->stub ()->add_forward_profiles (mprofile);
- // This has to be and is thread safe.
- // TAO_Stub::add_forward_profiles() already makes a copy of the
- // MProfile, so do not make a copy here.
-
-
- // We may not need to do this since TAO_GIOP_Invocations
- // get created on a per-call basis. For now we'll play it safe.
- if (invocation->stub ()->next_profile () == 0)
- ACE_THROW (CORBA::TRANSIENT (
- CORBA::SystemException::_tao_minor_code (
- TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
- errno),
- CORBA::COMPLETED_NO));
-}
-
-void
-TAO_FT_Invocation_Endpoint_Selector::success (TAO_GIOP_Invocation *invocation)
-{
- invocation->stub ()->set_valid_profile ();
-}
-
-void
-TAO_FT_Invocation_Endpoint_Selector::close_connection (TAO_GIOP_Invocation *invocation)
-{
- // Get rid of any forwarding profiles and reset
- // the profile list to point to the first profile!
- // FRED For now we will not deal with recursive forwards!
- invocation->stub ()->reset_profiles ();
-}
-
-
-int
-TAO_FT_Invocation_Endpoint_Selector::select_endpoint_i(
- TAO_GIOP_Invocation *invocation
+bool
+TAO_FT_Invocation_Endpoint_Selector::select_primary (
+ TAO::Profile_Transport_Resolver *r,
+ ACE_Time_Value *max_wait_time
ACE_ENV_ARG_DECL)
{
- int retval =
- this->select_primary (invocation
- ACE_ENV_ARG_PARAMETER);
- ACE_CHECK_RETURN (-1);
+ // Grab the forwarded list
+ TAO_MProfile *prof_list =
+ ACE_const_cast (TAO_MProfile *,
+ r->stub ()->forward_profiles ());
+ TAO_MProfile &basep = r->stub ()->base_profiles ();
- // We havent got any information on the primary ie. we dont have a
- // primary in the profile at all or we have a primary selected. We
- // return now.
- if (retval == 0 || retval == 1)
- return retval;
+ if (prof_list ==0)
+ prof_list = &basep;
- // Ok, to the tricky portion. Primary is dead.
- if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) The primary is dead,"
- " selecting a secondary \n"));
-
- // @@ todo: We could hold & release the locks a couple of times
- // here. We need to look into this after 1.2.1 for better
- // performance.
- if (this->is_rewound_ == 0)
- {
- // .. grab the lock
- ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
- guard,
- *(invocation->stub ()->profile_lock ()),
- 0));
-
- // DOUBLE checked optimization pattern
- if (this->is_rewound_ == 0)
- {
- // Reset the profile list
- invocation->stub ()->reset_profiles_i ();
+ if (prof_list == 0)
+ return false;
- // Set the flag
- this->is_rewound_ = 1;
- }
- }
+ // Did not succeed. Try to look for primaries all over the place
+ CORBA::ULong sz =
+ prof_list->size ();
- do
+ // Iterate through the list in a circular fashion. Stop one before
+ // the list instead of trying the same thing again.
+ for (CORBA::ULong i = 0;
+ i != sz;
+ ++i)
{
- IOP::TaggedComponent tagged_component;
- tagged_component.tag = IOP::TAG_FT_PRIMARY;
-
- // Get the tagged component from the profile
- TAO_Tagged_Components &pfile_tagged =
- invocation->stub ()->profile_in_use ()->tagged_components ();
+ TAO_Profile *tmp = prof_list->get_profile (i);
- // If it is a primary just skip to the next profile. We know
- // that the primary has failed anyway..
- if (pfile_tagged.get_component (tagged_component) != 1)
- {
- invocation->profile (invocation->stub ()->profile_in_use ());
- invocation->endpoint (invocation->profile ()->endpoint ());
-
- int status =
- this->endpoint_from_profile (invocation
+ bool retval =
+ this->check_profile_for_primary (tmp
ACE_ENV_ARG_PARAMETER);
- ACE_CHECK_RETURN (-1);
+ ACE_CHECK_RETURN (false);
- if (status == 1)
- return 1;
+ // Choose a non-primary
+ if (retval == true && tmp != 0)
+ {
+ retval =
+ this->try_connect (r,
+ tmp,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (retval == true)
+ return true;
}
}
- while (invocation->stub ()->next_profile_retry () != 0);
- // If we get here, we completely failed to find an endpoint selector
- // that we know how to use, so throw an exception.
- ACE_THROW_RETURN (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
- CORBA::COMPLETED_NO),
- 0);
+ return false;
}
-int
-TAO_FT_Invocation_Endpoint_Selector::select_primary (
- TAO_GIOP_Invocation *invoc
+bool
+TAO_FT_Invocation_Endpoint_Selector::select_secondary (
+ TAO::Profile_Transport_Resolver *r,
+ ACE_Time_Value *max_wait_time
ACE_ENV_ARG_DECL)
{
- // Get the current profile
- TAO_Profile *temp_profile = 0;
+ // Grab the forwarded list
+ TAO_MProfile *prof_list =
+ ACE_const_cast (TAO_MProfile *,
+ r->stub ()->forward_profiles ());
- // Get the forwarded profile if it exists
- if (invoc->stub ()->forward_profiles ())
- {
- TAO_MProfile *tmp =
- ACE_const_cast (TAO_MProfile *,
- invoc->stub ()->forward_profiles ());
- temp_profile =
- tmp->get_current_profile ();
- }
- else
- {
- temp_profile =
- invoc->stub ()->base_profiles ().get_current_profile ();
- }
+ TAO_MProfile &basep =
+ r->stub ()->base_profiles ();
- int retval = 0;
+ if (prof_list ==0)
+ prof_list = &basep;
- if (temp_profile)
- {
- // Check whether we have a primary profile in hand.
- retval =
- this->check_profile_for_primary (invoc,
- temp_profile
- ACE_ENV_ARG_PARAMETER);
- ACE_CHECK_RETURN (-1);
- }
- else
- return 0;
+ if (prof_list == 0)
+ return false;
- // If we have a primary just return
- if (retval == 1)
- return retval;
+ CORBA::ULong sz =
+ prof_list->size ();
- // If we have detected a failure
- if (retval == -1)
+ for (CORBA::ULong i = 0;
+ i != sz;
+ ++i)
{
- // .. grab the lock
- ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
- guard,
- *invoc->stub ()->profile_lock (),
- 0));
+ TAO_Profile *tmp =
+ prof_list->get_profile (i);
- // set the primary flag to be dead..
- this->is_primary_alive_ = 0;
+ bool retval =
+ this->check_profile_for_primary (tmp
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
- // .. and return
- return retval;
+ // Choose a non-primary
+ if (retval == false && tmp != 0)
+ {
+ retval =
+ this->try_connect (r,
+ tmp,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (retval == true)
+ return true;
+ }
}
+ return false;
+}
- // Doing the above helps us to avoid a lock for every
- // invocation. The funda is this. Try to select the first profile in
- // the list of profiles. If it is a primary, life is just great from
- // there. If not, hold a lock and go through the list to pick
- // one. The second invocation would just use that profile as the
- // starting point. Theoretically we should have just one lock if the
- // primary is hidden somewhere else.
-
- // If we know that the primary is dead return a -1, to choose a
- // secondary.
- if (this->is_primary_alive_ == 0)
- return -1;
+bool
+TAO_FT_Invocation_Endpoint_Selector::try_connect (
+ TAO::Profile_Transport_Resolver *r,
+ TAO_Profile *profile,
+ ACE_Time_Value *max_wait_time
+ ACE_ENV_ARG_DECL)
+{
+ r->profile (profile);
- // Now grab the lock
- ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
- guard,
- *invoc->stub ()->profile_lock (),
- 0));
+ size_t endpoint_count =
+ r->profile ()->endpoint_count ();
- temp_profile =
- invoc->stub ()->base_profiles ().get_next ();
+ TAO_Endpoint *ep =
+ r->profile ()->endpoint ();
- // While the profile is not null
- while (temp_profile)
+ for (size_t i = 0; i < endpoint_count; ++i)
{
- // Check whether we have a primary profile in hand.
- retval =
- this->check_profile_for_primary (invoc,
- temp_profile
- ACE_ENV_ARG_PARAMETER);
- ACE_CHECK_RETURN (-1);
+ TAO_Base_Transport_Property desc (ep);
+
+ bool retval =
+ r->try_connect (&desc,
+ max_wait_time
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // @@ Good place to handle timeouts.. We can omit timeouts and
+ // go ahead looking for other things... There are some small
+ // issues that needs ironed out first in the invocation
+ // classes.
- if (retval == 1 || retval == -1)
- return retval;
+ // Check if the connect has completed.
+ if (retval)
+ return true;
- temp_profile =
- invoc->stub ()->base_profiles ().get_next ();
+ // Go to the next endpoint in this profile.
+ ep = ep->next ();
}
- // Return failure. We havent found any
- // @@ Here is where another issue kicks in. Do we flag this
- // condition as an error. May be not. Probably the client
- // ORB that is FT compliant, has received an IOR from a
- // non-compliant ORB. We cannot think this of an error. Rather we
- // need to fall back on the default methodology. That would mean
- // that we return 0 and allow the ORB to do the rest.
- return 0;
-
- // @@ All said and done, what if we receive an IOGR from a
- // FT-compliant ORB with no primaries?
- // Ans: The default usage of the profile in the list
- // as the start point would NOT be a mistake. We should
- // get a LOCATION_FORWARD or some such thing to get to
- // the primary finally.
+ return false;
}
-
-int
+bool
TAO_FT_Invocation_Endpoint_Selector::check_profile_for_primary (
- TAO_GIOP_Invocation *invocation,
- TAO_Profile*pfile
- ACE_ENV_ARG_DECL)
+ TAO_Profile *pfile
+ ACE_ENV_ARG_DECL_NOT_USED)
{
+ if (pfile == 0)
+ return false;
+
IOP::TaggedComponent tagged_component;
tagged_component.tag = IOP::TAG_FT_PRIMARY;
@@ -310,43 +223,14 @@ TAO_FT_Invocation_Endpoint_Selector::check_profile_for_primary (
pfile->tagged_components ();
// Search for the TaggedComponent that we want
- if (pfile_tagged.get_component (tagged_component) == 1)
- {
- if (TAO_debug_level > 2)
- {
- ACE_DEBUG ((LM_DEBUG,
- "(%P|%t) TAO-FT - Got a primary component \n"));
- }
-
- invocation->profile (pfile);
- invocation->endpoint (invocation->profile ()->endpoint ());
-
- int status =
- this->endpoint_from_profile (invocation
- ACE_ENV_ARG_PARAMETER);
- ACE_CHECK_RETURN (-1);
-
- if (status == 1)
- {
- if (TAO_debug_level > 4)
- ACE_DEBUG ((LM_DEBUG,
- "(P|%t) TAO-FT - Got a valid primary \n"));
-
- return 1;
- }
- else
- {
- if (TAO_debug_level > 2)
- ACE_ERROR ((LM_ERROR,
- "(P|%t) TAO-FT - We have a primary profile,"
- " but it is unreachable \n"));
- return -1;
- }
+ if (pfile_tagged.get_component (tagged_component) != 1)
+ return false;
+ if (TAO_debug_level > 2)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) TAO-FT - Got a primary component \n"));
}
- if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- "(P|%t) TAO-FT - Not a primary profile \n"));
- return 0;
+ return true;
}