[omniORB] oneway method (bug?)

Sai-Lai Lo S.Lo@uk.research.att.com
06 Oct 1999 16:23:52 +0100


Jean,

>>>>> Jean-Francois Tremblay writes:

> running on IRIX 6.5.4, IDO 7.2.1, omniORB2.7.1 I have the following
> behavior.

> If I use an object reference and that I wait so the underlying
> connection times out before reusing the object reference, then,
> afterwards I can no longer method declares as "oneway" the other method
> are fine and the connection is transparently reinitiated, however the
> oneway method no longer work. I've tried with several oneway method none
> still work if I let the connection times out.

> So is it a bug or a feature of Corba that I don't understand?

I'm not sure I understand what you are trying to achieve or exactly what
problems you are having. You seem to think there is a problem with oneway
call. If you try this test program (and run it with -ORBtraceLevel 25), you 
will see that the ORB does close down an idle connection and a subsequent
oneway call does cause the ORB to reconnect. No oneway call is lost.

You can even set up the server side to timeout and close the idle
connection. In this case, there is a race condition if the server
side close the idle connection *at the same time* the client does a oneway
call. Under this connection, whether the client side ORB sees the
connection has been broken (and hence retry) while it is sending the bits
depends on the TCP implementation of your platform. If the close connection
status is not propagated timely to the client ORB while it is sending the
bits, it wouldn't know the oneway call cannot get through. So it won't
retry the call as it normally does.

So what can you do?

1. You can stop using oneway if you want 100% guarantee of delivery.
or
2. You set the server side connection timeout to a larger value than the
   client side connection timeout (which is the default behaviour with
   2.8.0).

Is this a bug? I'm afraid the way GIOP is specified there is no way to
avoid this race condition. One can fix this by waiting for an ACK from the
server side but then that just turns oneway into request-reply.

Sai-Lai

-------------- onewaytm.idl --------------
interface OW {
  oneway void op(in string a);
};

-------------------------------------------

----------- client.cc ----------------
#include <iostream.h>
#include "onewaytm.hh"

int
main (int argc, char **argv) 
{
  // set outgoing to timeout idle connection after 20 seconds.
  omniORB::idleConnectionScanPeriod(omniORB::idleOutgoing,20);

  CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");

  if (argc < 2) {
    cerr << "usage: client <object reference>" << endl;
    return 1;
  }

  try {
    CORBA::Object_var obj = orb->string_to_object(argv[1]);
    OW_var o = OW::_narrow(obj);
    if (CORBA::is_nil(o)) {
      cerr << "Cannot invoke on a nil object reference." << endl;
      return 1;
    }
    int count = 10;
    while (count--) {
      CORBA::String_var src = (const char*) "Hello!";
      o->op(src);
      omni_thread::sleep(30);
    }
  }
  catch(...) {
    cerr << "Caught a system exception." << endl;
  }

  orb->NP_destroy();

  return 0;
}

-----------------------------------
------------ server.cc ---------------------------
#include <iostream.h>
#include "onewaytm.hh"

class OW_i : public _sk_OW {
public:
  void op(const char* a) {
    omniORB::logger log("OW_i: ");
    log << a << "\n";
  }
};

int
main(int argc, char **argv)
{
  CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
  CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");

  OW_i *myobj = new OW_i();
  myobj->_obj_is_ready(boa);

  {
    OW_var myobjRef = myobj->_this();
    CORBA::String_var p = orb->object_to_string(myobjRef);
    cerr << "'" << (char*)p << "'" << endl;
  }

  boa->impl_is_ready();
  return 0;
}
----------------------------------------------------




-- 
Sai-Lai Lo                                   S.Lo@uk.research.att.com
AT&T Laboratories Cambridge           WWW:   http://www.uk.research.att.com 
24a Trumpington Street                Tel:   +44 1223 343000
Cambridge CB2 1QA                     Fax:   +44 1223 313542
ENGLAND