[omniORB] onewat message disappears

Sai-Lai Lo S.Lo@orl.co.uk
10 Jun 1998 10:12:24 +0100


This sounds bad.

One explanation is that a System Exception was raised in the server but
because this is a oneway call it is not propagated back to the client.
Hence the oneway seems to disappear.

One reason this could happen is the message size has exceeded the limit
(2Mbytes in 2.5.0). This value can be increased using
omniORB::MaxMessageSize.

To verify if this is the problem, apply the patch to giopServer.cc at the
end of this message and run the server with -ORBtraceLevel 20 and see if
any of the additional trace message comes up.

I'm interested to know if you see any of the new trace messages popping up.

Regards,

Sai-Lai



Mark Rabotnikov <mark@netmanage.co.il> writes:
> 
> Jan Lessner wrote:
> 
> > Hello omniOrb'ers
> > I encountered problems with oneway calls which sometimes just seem to
> > "disappear" on there way from the client to the server. Both
> > applications don't signal any prticular problems, neither in the
> > debugger nor with purify, nor with -ORBtraceLevel 20. So everything
> > should be fine, but although the message seams to be sent correctly, the
> > appropriate method in the server object is not invoked.
> > The problem is quite difficult to reproduce, it seems to depend on
> > certain timing conditions.
> >
> > Did anyone else ever have this problem?
> >
> > Regards,
> >
> >         Jan Lessner, C-LAB
> 
> Yes, I've noticed the similar problem and posted it to the list on 
> 17 Feb 1998.
> 


Patch to giopServer.cc (omniORB_2.5.0), line 392:

#define CHECK_AND_MAYBE_MARSHALL_SYSTEM_EXCEPTION(exrepoid,exvar) do {\
    if (!strandIsDying() && (pd_state == RequestIsBeingProcessed || \
	pd_state == WaitingForReply)) \
      { \
	if (pd_state == RequestIsBeingProcessed) { \
           RequestReceived(1); \
	} \
	if (!pd_response_expected) \
	{ \
          if (omniORB::traceLevel >= 20) { \
             cerr << "GIOP_S::HandleRequest: system exception raised on oneway call." \
          } \
	  SendMsgErrorMessage(); \
          ReplyCompleted(); \
	} \
        else \
        { \
	  MarshallSystemException(this,SysExceptRepoID:: exrepoid ,exvar); \
	}  \
      } \
    else { \
	throw; \
    } \
  } while (0)

void
GIOP_S::HandleRequest(CORBA::Boolean byteorder)
{
  CORBA::ULong msgsize;

  try {
    // This try block catches any exception that might raise during
    // the processing of the request header
    msgsize <<= *this;
    if (msgsize > MaxMessageSize()) {
      if (omniORB::traceLevel >= 20) {
         cerr << "GIOP_S::HandleRequest: message size has exceeded "
              << MaxMessageSize() << endl;
      }
      SendMsgErrorMessage();
      setStrandIsDying();
      throw CORBA::COMM_FAILURE(0,CORBA::COMPLETED_NO);
    }

    RdMessageSize(msgsize,byteorder);  // Set the size of the message body.
  
    // XXX Do not support any service context yet, 
    // XXX For the moment, skips the service context
    CORBA::ULong svcccount;
    CORBA::ULong svcctag;
    CORBA::ULong svcctxtsize;
    svcccount <<= *this;
    while (svcccount-- > 0) {
      svcctag <<= *this;
      svcctxtsize <<= *this;
      skip(svcctxtsize);
    };

    pd_request_id <<= *this;

    pd_response_expected <<= *this;

    CORBA::ULong keysize;
    keysize <<= *this;
    if (keysize != sizeof(omniObjectKey)) {
      // This key did not come from this orb.
      // silently skip the key. Initialise pd_objkey to all zeros and
      // let the call to locateObject() below to raise the proper exception
      pd_objkey = omniORB::nullkey();
      skip(keysize);
    }
    else {
      get_char_array((CORBA::Char *)&pd_objkey,keysize);
    }

    CORBA::ULong octetlen;
    octetlen <<= *this;
    if (octetlen > OMNIORB_GIOPDRIVER_GIOP_S_INLINE_BUF_SIZE)
      {
	// Do not blindly allocate a buffer for the operation string
	// a poison packet might set this to a huge value
	if (octetlen > RdMessageUnRead()) {
	  throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO);
	}
	CORBA::Octet *p = new CORBA::Octet[octetlen];
	if (!p)
	  throw CORBA::NO_MEMORY(0,CORBA::COMPLETED_NO);
	pd_operation = p;
      }
    get_char_array((CORBA::Octet *)pd_operation,octetlen);

    octetlen <<= *this;
    if (octetlen > OMNIORB_GIOPDRIVER_GIOP_S_INLINE_BUF_SIZE)
      {
	// Do not blindly allocate a buffer for the principal octet vector
	// a poison packet might set this to a huge value
	if (octetlen > RdMessageUnRead()) {
	  throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO);
	}
	CORBA::Octet *p = new CORBA::Octet[octetlen];
	if (!p)
	  throw CORBA::NO_MEMORY(0,CORBA::COMPLETED_NO);
	pd_principal = p;
      }
    get_char_array((CORBA::Octet *)pd_principal,octetlen);
  }
  catch (const CORBA::MARSHAL &ex) {
    RequestReceived(1);
    if (omniORB::traceLevel >= 20) {
       cerr << "GIOP_S::HandleRequest: Exception encountered in unmarshalling the header." 
	    << endl;
    }
    SendMsgErrorMessage();
    pd_state = GIOP_S::Idle;
    return;
  }
  catch (const CORBA::NO_MEMORY &ex) {
    RequestReceived(1);
    if (omniORB::traceLevel >= 20) {
       cerr << "GIOP_S::HandleRequest: Exception (no memory) encountered in unmarshalling the header." 
	    << endl;
    }
    MarshallSystemException(this,SysExceptRepoID::NO_MEMORY,ex);
    return;
  }

    // Note: If this is a one way invocation, we choose to return a 
    // MessageError Message instead of returning a Reply with System Exception
    // message because the other-end says do not send me a reply!

  omniObject *obj = 0;    
  try {
    // In future, we have to partially decode the object key to
    // determine which object manager it belongs to.
    // For the moment, there is only one object manager- the rootObjectManager.
    obj = omni::locateObject(omniObjectManager::root(),pd_objkey);
    if (!obj->dispatch(*this,(const char *)pd_operation,pd_response_expected))
	{
	  if (!obj->omniObject::dispatch(*this,(const char*)pd_operation,
					pd_response_expected))
	    {
	      RequestReceived(1);
	      throw CORBA::BAD_OPERATION(0,CORBA::COMPLETED_NO);
	    }
	}
    
  }
  catch (const CORBA::OBJECT_NOT_EXIST &ex) {

    if (!obj && pd_response_expected && MapKeyToObjectFunction) {
      // Cannot find the object in the object table. If the application
      // has registered a loader, do an upcall to locate the object.
      // If the returned value is not a nil object reference, send a
      // LOCATION_FORWARD message to the client to instruct it to retry
      // with the new object reference.
      //
      // Limitation: if this invocation is oneway, one cannot reply with
      //             a LOCATION_FORWARD message, in that case, just
      //             treat this as a normal OBJECT_NOT_EXIST and let
      //             the code below to deal with it.
      //
      CORBA::Object_var newDestination= MapKeyToObjectFunction(pd_objkey);
      if (!CORBA::is_nil(newDestination)) {
	// Note that we have completed the object request
	RequestReceived(1); 
	
	// Build and send the location forward message...
	size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize();
	msgsize = CORBA::Object::NP_alignedSize(newDestination, msgsize);
	InitialiseReply(GIOP::LOCATION_FORWARD,(CORBA::ULong)msgsize);
	CORBA::Object::marshalObjRef(newDestination, *this);
	
	// All done...
	ReplyCompleted(); return;
      }
    }

    if (!obj) {
      RequestReceived(1);
      if (!pd_response_expected) {
	// This is a one way invocation, we choose to return a MessageError
	// Message instead of returning a Reply with System Exception
	// message because the other-end says do not send me a reply!
       if (omniORB::traceLevel >= 20) {
          cerr << "GIOP_S::HandleRequest: OBJECT_NOT_EXIST raised in oneway." 
	       << endl;
        }
	SendMsgErrorMessage();
	ReplyCompleted();
      }
      else {
	MarshallSystemException(this,SysExceptRepoID::OBJECT_NOT_EXIST,ex);
      }
    }
    else {
      omni::objectRelease(obj); obj = 0;
      CHECK_AND_MAYBE_MARSHALL_SYSTEM_EXCEPTION (OBJECT_NOT_EXIST,ex);
    }      
  }
  catch (const CORBA::UNKNOWN &ex) {
    if (obj) omni::objectRelease(obj); obj = 0;
    CHECK_AND_MAYBE_MARSHALL_SYSTEM_EXCEPTION (UNKNOWN,ex);




-- 
Dr. Sai-Lai Lo                          |       Research Scientist
                                        |
E-mail:         S.Lo@orl.co.uk          |       Olivetti & Oracle Research Lab
                                        |       24a Trumpington Street
Tel:            +44 223 343000          |       Cambridge CB2 1QA
Fax:            +44 223 313542          |       ENGLAND