CORBA Object Lifecycle

CORBA does not have the concept of distinct client and server applications. An application may both make and receive CORBA method calls. When it makes CORBA method calls it is behaving as a ‘client’. When it receives CORBA method calls it is behaving as a ’server’.

The four kinds of CORBA object.

Client Side

Object_Reference semantically equivalent to a C++ pointer to the servant object. Actually refers to the Proxy object in the client’s ORB.

Created from an IOR (which may be read from the naming service), directly by a call to servant->_this(), or from the result of a CORBA method call. Destroyed when it goes out of scope.

Proxy_Object implements a CORBA interface, as defined in an IDL. However, the proxy does not contain application code. Instead it reponds to message calls by locating the actual CORBA object across the network (or perhaps within the same application) and passing on the call to that object.

Implicitly created by CORBA when an Object Reference is created. The Proxy object maintains a count of the number of Object References IN THIS EXECUTABLE that currently point to it. When the reference count drops to zero, the Proxy is automatically destroyed.

Server Side

Transient Objects

Transient objects live short lives that end when their owning POA is destroyed. Transient objects’ IORs should not be listed in the naming service, as they will quickly become out-of-date.

CORBA_Object created by and owned by the server’s default POA. Owns a pointer to the C++ Servant object. The IOR uniquely ‘names’ a CORBA Object. The Object receives CORBA messages from a Proxy, and converts it into a method call to the Servant.

Created when a servant object is activated in the POA. The best way to do this is just to call servantPtr->_this(). When the servant is not activated, _this() creates the transient Object in the default POA as an implicit side-effect.

Destroyed when the parent POA is destroyed (e.g. at ORB shutdown) or explicitly, by a call to poa->deactivate_object(objectId).

Servant implements the interface defined in the IDL file. Called by the CORBA object when method invokations come in from the ORB.

Created by the user by calling C++ new. Initially, new Servants are not connected to an Object. Once _this() has been called, the relationship is established and continues for the lifetime of the CORBA object.

Servants should inherit from the base class RefCountServantBase, and have private destructors. Once the servant’s Object has been activated in the POA, the reference count should be decremented, this hands ownership of the Servant to the CORBA Object. Destroy the Servant by deactivating its Object in the POA.

Examples: XmlDocument::destroy(), SupplierImpl::destroy()

Persistent Objects

Persistent objects are CORBA Objects that may outlive their POA. Objects that are registered in the naming service should usually be persistent. The activation of persistent objects is a little different from transient objects, but clean-up is identical. The Servant class should inherit from RefCountServantBase, and each instance should decrement its reference count once it has been activated.

Persistent Objects must be given an explicit object ID, you cannot just use the default made-up by the POA. Make an Object ID

ObjectIdvar oid = stringtoObjectId("MyObject");

and then activate the servant with a call to:

poa->activateobjectwithid(oid,servantPtr)

The default POA will not accept this call, you must create a new POA with the following policies:

IdAssignmentPolicy = USER
LifespanPolicy = PERSISTENT

Finally, an application that contains persistent objects must be started on the same port each time. OmniORB provides the following option to explicitly set the server port:

> myapp -ORBendPoint giop:tcp::1234

starts myapp on port 1234 (all local interfaces).

Example:

    // Create a child POA, with a different policy.
    PortableServer::IdAssignmentPolicy_var iap=
      rootPoa->create_id_assignment_policy(PortableServer::USER_ID);
    PortableServer::LifespanPolicy_var      lp=
      rootPoa->create_lifespan_policy(PortableServer::PERSISTENT);

    CORBA::PolicyList policyList;
    policyList.length(2);
    policyList[0]=iap;
    policyList[1]=lp;

    PortableServer::POA_var poa =
      rootPoa->create_POA(
        "child", // adapter name
        PortableServer::POAManager::_nil(),
        policyList
      );

    // Make a new Servant
    ExampleImpl* myExample =new Example_i();
    
    // Make an object ID.
    PortableServer::ObjectId_var myExample_iid =
      PortableServer::string_to_ObjectId("Example");

    // Activate the object
    poa->activate_object_with_id(myExample_iid.in(),myExample_i);

Comment · RSS · TrackBack

  1. Thomas said,

    9 December, 2011 @ 09:41

    Helpful summary not only for OMNIOrb users.

Leave a Comment

Sponsors