The Message pseudo-interface

The IDL for the message interface in ORBLink is:

  pseudo interface Message{
    enum MessageDirection {incoming,outgoing,unknown}; 
    readonly attribute MessageDirection direction;     
    enum MessageType {Request,Reply,CancelRequest,LocateRequest,
    readonly attribute MessageType type;
    readonly attribute junction ForwardingJunction;

The corresponding Lisp class is named ORBLink:message and instances of that class represent IIOP messages.

Suppose m is bound to an instance of ORBLink:message. Then the form

(op:direction m)

corresponding to the direction attribute will return a value of type ORBLink:MessageDirection, that is, one of :incoming, :outgoing, or :unknown depending on whether m represents an incoming, outgoing, or message of unknown direction.

The form

(op:type m)

corresponding to the type attribute of m returns a keyword of type ORBLink:MessageType, a member of (:request :reply :cancelrequest :locaterequest :locatereply :closeconnection :messageerror :fragment).

The ForwardingJunction attribute of m holds an instance of class ORBLink:Junction which represents the junction from which the message was received (if an incoming message) or to which the message is being sent (if an outgoing message).

Only Request messages can actually be obtained using exposed APIs.

A Request message (a message whose type attribute is :request) is obtained as follows.

When a ServerJunction receives an IIOP Request message from a client, the operands are dispatched to the appropriate local implementation object which then executes the body of the corba:define-method corresponding to the operation requested by the message. Within the dynamic scope of that body, the special variable orblink:*message* is bound to the corresponding request message.

The appropriate server junction can then be obtained from the value of the ForwardingJunction attribute of message.

The IDL and implementation in examples/test/test.idl and examples/test/ include a simple example for accessing the message from the body of a corba:define-method form.

The relevant IDL is in examples/test/test.idl:

 module idltest{ interface test
    oneway void testmessage (in unsigned short delay);

The associated implementation class in examples/test/ is:

(defclass test-implementation (idltest:test-servant)
  ((message :accessor get-message)))

The implementation of the operation defined in the IDL is given by:

(corba:define-method testmessage ((this test-implementation) delay)
  (sleep delay)
  (format t "testmessage: got message of: ~s~%" orblink:*message* this)
  (setf (get-message this) orblink:*message*)

(The delay can be used easily to verify that orblink:*message* is bound to 
different messages in different threads).

Thus, the serverjunction corresponding to a message can be obtained via:

(op:forwardingjunction orblink:*message*)
In conjunction with the handlejunctionclose operation and the HandleJunctionClosePolicy attribute in pseudo interface ORBLink::ORB, these features allow the user, for example, to determine which implementations correspond to which server junctions and to perform local cleanup if desired.