[omniORB] client-side timeouts
Peter Bauer
PBHD@compuserve.com
Fri, 8 Oct 1999 07:49:10 -0400
Hello,
while playing with client-side timeouts, I found different =
things I want to ask now. My test-"Environment" consists =
of two programs, the server's object contains one callable =
method, which does nothing else but sleeping for a large
amount of time, and the client attempts to invoke this =
method within a loop with timeouts starting by 1 and being
increased by one for each invocation =
- without having a transient exception-handler installed, =
the first invocation is duplicated by =
OmniProxyCallWrapper::invoke, because it is reusing an =
existing Strand (which I think gets created by the =
invocation of assertObjectExistent), and does a retry =
when the first invocation fails. Subsequent invocations =
(which all timeout) will be sent only once, because the =
flag existent_and_type_verified is then set and the =
assertObjectExistent does nothing, so no strand-recycling =
takes place and a exception is thrown (reuse is false =
in that case)
- having a transient exception-handler installed, which =
returns 0, every invocation is done only once (which =
is the behavoiur I would expect).
- having a CommFailure exception-handler installed, which =
tells the runtime to retry the call, the invocation is =
sent for each failure again to the server. So my =
understanding of a Comm-Failure-Handler which returns =
conditionless 1 is now, that it acts the same way than =
a client, which does a =
{int f=3D1;do {try {p->x();f=3D0;} catch (...) {}}while(f);}
What I would like more, is that if my CommFailure-handler =
returns true, and the network-connection by itself is =
still ok (Hmm, currently its at this point already broken =
by intent by the scavenger), then the client continues =
to wait for the original invoked remote method. With =
this behaviour, I could implement different timeouts =
on different invocations by setting a callTimout e.g. =
to 10, and then installing different handlers on a =
per-proxy-basis, which then could decide to wait longer =
depending on the involved proxy.
- trying to deinstall a transient exception-handler by =
calling omniORB::installTransientExceptionHandler(0,0) =
results in a core when the next transient exception =
occurs. I think a 0 pointer should reinstall the =
default handler?
- Because my clients talk to different servers, for which =
different timeouts need to be used, and because the =
above trick with the CommFailure handler doesn't work, =
I implemented a way to set individual timeouts on a =
per-proxy basis, for which the patch follows below =
(the line numbers perhaps are not correct, because =
there are some trace-messages inserted elsewhere, =
and the deccxx5.6 patch is installed). These =
modifications are ok for me, but for now I'm not sure =
wether a Strand involved in a remote call can be used =
in parallel by another thread. (So one Strand would =
have two outstanding remote calls). If this is true, =
the per-proxy timeout of the first proxy would be =
overwritten by the second one. (Which would be still =
ok for me) (After applying this patch, I had to =
recompile everything, a simple make in the src-dir did =
not work. (maybe because my system uses a cockoo-clock
as system-timer))
Gruss Peter Bauer
diff -c -r original/omniORB_280/include/omniORB2/giopDriver.h
omniORB/include/omniORB2/giopDriver.h
*** original/omniORB_280/include/omniORB2/giopDriver.h Sat Jun 26 19:55:=
19
1999
--- omniORB/include/omniORB2/giopDriver.h Thu Oct 7 18:06:33 1999
***************
*** 213,219 ****
const char *opname,
const size_t opnamesize,
const size_t msgsize,
! const _CORBA_Boolean oneway);
// Initialise a Request message.
// Note: <msgsize> is the size of the whole message including the
// GIOP message header and the Request message header.
--- 213,220 ----
const char *opname,
const size_t opnamesize,
const size_t msgsize,
! const _CORBA_Boolean oneway,
! const time_t timeout=3D-1);
// Initialise a Request message.
// Note: <msgsize> is the size of the whole message including the
// GIOP message header and the Request message header.
diff -c -r original/omniORB_280/include/omniORB2/omniInternal.h
omniORB/include/omniORB2/omniInternal.h
*** original/omniORB_280/include/omniORB2/omniInternal.h Mon Aug 1=
6
21:33:07 1999
--- omniORB/include/omniORB2/omniInternal.h Thu Oct 7 18:08:18 1999
***************
*** 521,527 ****
void noExistentCheck() { pd_flags.existent_and_type_verified =3D 1; }=
// This function instructs the ORB to skip the existence test perform=
ed
// in assertObjectExistent().
! =
static omni_mutex objectTableLock;
static omniObject* proxyObjectTable;
static omniObject** localObjectTable;
--- 521,533 ----
void noExistentCheck() { pd_flags.existent_and_type_verified =3D 1; }=
// This function instructs the ORB to skip the existence test perform=
ed
// in assertObjectExistent().
! time_t getTimeout ();
! void setTimeout (time_t);
static omni_mutex objectTableLock;
static omniObject* proxyObjectTable;
static omniObject** localObjectTable;
***************
*** 548,554 ****
};
int pd_refCount;
omniObject* pd_next;
- =
struct {
_CORBA_UShort proxy : 1;
_CORBA_UShort disposed : 1;
--- 554,559 ----
***************
*** 560,565 ****
--- 565,571 ----
} pd_flags;
=
IOP::TaggedProfileList* pd_iopprofile;
+ time_t pd_timeout;
=
inline int getRefCount() const { return pd_refCount; }
inline void setRefCount(int count) { pd_refCount =3D count; }
diff -c -r original/omniORB_280/src/lib/omniORB2/orbcore/giopClient.cc
omniORB/src/lib/omniORB2/orbcore/giopClient.cc
*** original/omniORB_280/src/lib/omniORB2/orbcore/giopClient.cc Mon Aug 3=
0
18:50:17 1999
--- omniORB/src/lib/omniORB2/orbcore/giopClient.cc Fri Oct 8 10:22:=
20
1999
***************
*** 128,140 ****
const char *opname,
const size_t opnamesize,
const size_t msgsize,
! const CORBA::Boolean oneway)
{
if (pd_state !=3D GIOP_C::Idle)
throw omniORB::fatalException(__FILE__,__LINE__,
"GIOP_C::InitialiseRequest() entered with the wrong state.");
=
! clicksSet(StrandScavenger::clientCallTimeLimit());
=
size_t bodysize
=3Dmsgsize-sizeof(MessageHeader::Request)-sizeof(CORBA::ULong);
if (bodysize > MaxMessageSize()) {
--- 128,141 ----
const char *opname,
const size_t opnamesize,
const size_t msgsize,
! const CORBA::Boolean oneway,
! const time_t timeout)
{
if (pd_state !=3D GIOP_C::Idle)
throw omniORB::fatalException(__FILE__,__LINE__,
"GIOP_C::InitialiseRequest() entered with the wrong state.");
=
! clicksSet(StrandScavenger::clientCallTimeLimit(timeout));
=
size_t bodysize
=3Dmsgsize-sizeof(MessageHeader::Request)-sizeof(CORBA::ULong);
if (bodysize > MaxMessageSize()) {
diff -c -r original/omniORB_280/src/lib/omniORB2/orbcore/proxyCall.cc
omniORB/src/lib/omniORB2/orbcore/proxyCall.cc
*** original/omniORB_280/src/lib/omniORB2/orbcore/proxyCall.cc Mon Jun 2=
8
12:48:22 1999
--- omniORB/src/lib/omniORB2/orbcore/proxyCall.cc Thu Oct 7 18:03:=
21
1999
***************
*** 90,96 ****
giop_client.InitialiseRequest(ropeAndKey.key(),
ropeAndKey.keysize(),
call_desc.operation(),
call_desc.operation_len(),
! message_size, 0);
=
// Marshal the arguments to the operation.
call_desc.marshalArguments(giop_client);
--- 90,96 ----
giop_client.InitialiseRequest(ropeAndKey.key(),
ropeAndKey.keysize(),
call_desc.operation(),
call_desc.operation_len(),
! message_size, 0, o->getTimeout());
=
// Marshal the arguments to the operation.
call_desc.marshalArguments(giop_client);
***************
*** 227,233 ****
giop_client.InitialiseRequest(ropeAndKey.key(),
ropeAndKey.keysize(),
call_desc.operation(),
call_desc.operation_len(),
! message_size, 1);
=
// Marshal the arguments to the operation.
call_desc.marshalArguments(giop_client);
--- 227,233 ----
giop_client.InitialiseRequest(ropeAndKey.key(),
ropeAndKey.keysize(),
call_desc.operation(),
call_desc.operation_len(),
! message_size, 1, o->getTimeout());
=
// Marshal the arguments to the operation.
call_desc.marshalArguments(giop_client);
diff -c -r original/omniORB_280/src/lib/omniORB2/orbcore/scavenger.cc
omniORB/src/lib/omniORB2/orbcore/scavenger.cc
*** original/omniORB_280/src/lib/omniORB2/orbcore/scavenger.cc Thu Sep 2=
3
16:36:33 1999
--- omniORB/src/lib/omniORB2/orbcore/scavenger.cc Fri Oct 8 11:38:=
30
1999
***************
*** 168,174 ****
// Internal interface to other parts of the ORB
=
int
! StrandScavenger::clientCallTimeLimit() { return clientCallTimeLimit_; }=
=
int =
StrandScavenger::serverCallTimeLimit() { return serverCallTimeLimit_; }=
--- 168,183 ----
// Internal interface to other parts of the ORB
=
int
! StrandScavenger::clientCallTimeLimit(int sec /*=3D=3D-1*/) {
! if (sec=3D=3D-1)
! return clientCallTimeLimit_; =
! else {
! if (sec && ScanPeriod)
! return ((sec >=3D ScanPeriod) ? sec : ScanPeriod) / ScanPeriod;
! else
! return INT_MAX;
! }
! }
=
int =
StrandScavenger::serverCallTimeLimit() { return serverCallTimeLimit_; }=
diff -c -r original/omniORB_280/src/lib/omniORB2/orbcore/scavenger.h
omniORB/src/lib/omniORB2/orbcore/scavenger.h
*** original/omniORB_280/src/lib/omniORB2/orbcore/scavenger.h Wed Sep 2=
2
21:21:48 1999
--- omniORB/src/lib/omniORB2/orbcore/scavenger.h Fri Oct 8 10:20:=
39
1999
***************
*** 65,71 ****
static void addRopeFactories(ropeFactoryList* l);
static void removeRopeFactories(ropeFactoryList* l);
=
! static int clientCallTimeLimit();
// This number determines how long the ORB is prepare to wait before
// giving up on a remove call on the client side and throws a
// COMM_FAILURE exception.
--- 65,71 ----
static void addRopeFactories(ropeFactoryList* l);
static void removeRopeFactories(ropeFactoryList* l);
=
! static int clientCallTimeLimit(int sec=3D-1);
// This number determines how long the ORB is prepare to wait before
// giving up on a remove call on the client side and throws a
// COMM_FAILURE exception.