[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.