Persistent Objects

Sai-Lai Lo S.Lo@orl.co.uk
Fri, 6 Jun 1997 10:48:21 +0100


>>>>> Edward Scott writes:

> If I wanted to do a demand driven style of persistent loading e.g. an
> object is only retrived from persistent store when an operation is
> performed on it will I need to modify omniOrb e.g. in
> GIOP_S::HandleRequest or omni::locateObject and add a mechanism to
> define how a particular type of object is loaded?

A more elegant solution is to use LOCATION_FORWARDING. When the first
operation is performed on the object, the object is retrived from
persistent store and instantiated. The object reference to this newly
instantiated object, which is different from the original object, is then
returned in a LOCATION_FORWARD message. 

All the hooks necessary to do this sort of trick is already in the ORB.
We have a design in the pipeline to allow applications to do these things
properly. Stay tuned.

In the meantime, see if this piece of example code helps. This program
takes an object reference as a command line argument, instantiated a redirect
object which stores the object ref internally. Any requests comes in for
the redirect object will receive a LOCATION_FORWARD message that points to
the first object. I think it is possible to adapt this example to do what
you want.

Regards,

Sai-Lai Lo



--------------------------- reDirect.h --------------------
#ifndef __REDIRECT_H__
#define __REDIRECT_H__

#include <omniORB2/CORBA.h>

class reDirect : public virtual omniObject, public virtual CORBA::Object {
public:

  reDirect(CORBA::Object_ptr fwdref); 

  reDirect(CORBA::Object_ptr fwdref,const omniORB::objectKey& mykey);

  virtual ~reDirect() {}

  CORBA::Object_ptr forwardReference() const;

  CORBA::Object_ptr _this();
  void _obj_is_ready(CORBA::BOA_ptr boa);
  CORBA::BOA_ptr _boa();
  void _dispose();
  omniORB::objectKey _key();
  virtual CORBA::Boolean dispatch(GIOP_S &s, const char *,CORBA::Boolean);

private:
  CORBA::Object_var pd_fwdref;
  reDirect();
};

-------------------------------- end ----------------------

--------------------------- reDirect.cc -------------------
#include <reDirect.h>

reDirect::reDirect(CORBA::Object_ptr fwdref) 
             : pd_fwdref(fwdref) 
{
  if (CORBA::is_nil(fwdref)) 
    throw CORBA::BAD_PARAM(0,CORBA::COMPLETED_NO);

  omniObject::PR_IRRepositoryId(fwdref->PR_getobj()->NP_IRRepositoryId());
  this->PR_setobj(this);
}

reDirect::reDirect(CORBA::Object_ptr fwdref, const omniORB::objectKey& mykey)
             : pd_fwdref(fwdref)
{
  if (CORBA::is_nil(fwdref)) 
    throw CORBA::BAD_PARAM(0,CORBA::COMPLETED_NO);

  omniObject::PR_IRRepositoryId(fwdref->PR_getobj()->NP_IRRepositoryId());
  this->PR_setobj(this);
  omniRopeAndKey l(0,(CORBA::Octet*)&mykey,(CORBA::ULong)sizeof(mykey));
  setRopeAndKey(l,0);
}

CORBA::Object_ptr
reDirect::forwardReference() const
{
  return CORBA::Object::_duplicate(pd_fwdref);
}

CORBA::Object_ptr
reDirect::_this()
{ 
  return CORBA::Object::_duplicate(this); 
}

void 
reDirect::_obj_is_ready(CORBA::BOA_ptr boa)
{ 
  boa->obj_is_ready(this);
}

CORBA::BOA_ptr
reDirect::_boa()
{ 
  return CORBA::BOA::getBOA();
}

void
reDirect::_dispose()
{ 
  _boa()->dispose(this);
}
  
omniORB::objectKey
reDirect::_key()
{
  omniRopeAndKey l;
  getRopeAndKey(l);
  return (*((omniORB::objectKey*)l.key()));
}

CORBA::Boolean
reDirect::dispatch(GIOP_S &s, const char *,CORBA::Boolean response)
{
  s.RequestReceived(1);
  if (!response) {
    // a one-way call, not allowed to give a reply
    // silently dump the request.
    s.ReplyCompleted();
    return 1;
  }
  size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize();
  msgsize = CORBA::Object::NP_alignedSize(pd_fwdref,msgsize);
  s.InitialiseReply(GIOP::LOCATION_FORWARD,(CORBA::ULong)msgsize);
  CORBA::Object::marshalObjRef(pd_fwdref,s);
  s.ReplyCompleted();
  return 1;
}

-------------------------- end ------------------------------

-------------------------- tombstone.cc ---------------------
#include <reDirect.h>

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");

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

  CORBA::Object_ptr obj = orb->string_to_object(argv[1]);
  if (CORBA::is_nil(obj)) {
    cerr << "Can't forward to a nil object." << endl;
    return -1;
  }

  reDirect* tombstone = new reDirect(obj);

  tombstone->_obj_is_ready(boa);

  {
    CORBA::Object_var objref = tombstone->_this();
    CORBA::String_var objstr = orb->object_to_string(objref);
    cerr << "'" << (char*)objstr << "'" << endl;
  }
  
  boa->impl_is_ready();

  return 0;
}

------------------------- end -----------------------