Using GMD


File-based GMD and memory-based GMD operate in exactly the same way. Whenever a GMD message is sent, a copy is stored in the GMD spool area, on disk or in memory, based on the values you specified for the options during configuration. The files for GMD are created automatically and only when necessary, typically on the first publish or first reception of a GMD message.

Java GMD Methods

The Java classes and methods used with GMD are listed in Table 5. Full API reference information for these classes and methods is online in Javadoc format and is provided with the SmartSockets product.

Table 5 Java Classes and Methods for GMD
Name
Description
TipcMsg.getDeliveryMode
Get the delivery mode of a message.
Equivalent C function: TipcMsgGetDeliveryMode
TipcMt.getDeliveryMode
Get the delivery mode of a message type.
Equivalent C function: TipcMtGetDeliveryMode
TipcMsg.getDeliveryTimeout
Get the delivery timeout of a message in seconds.
Equivalent C function: TipcMsgGetDeliveryTimeout
TipcMt.getDeliveryTimeout
Get the delivery timeout of a message type in seconds.
Equivalent C function: TipcMtGetDeliveryTimeout
TipcMsg.setDeliveryMode
Set the delivery mode of a message. Overrides the value set for a message by TipcMt.setDeliveryMode.
GMD settings: DELIVERY_SOME or DELIVERY_ALL
Equivalent C function: TipcMsgSetDeliveryMode
TipcMt.setDeliveryMode
Set the delivery mode of a message type.
GMD settings: DELIVERY_SOME or DELIVERY_ALL
Equivalent C function: TipcMtSetDeliveryMode
TipcMsg.setDeliveryTimeout
Set the delivery timeout of a message in seconds. Overrides the value set for a message by TipcMt.setDeliveryTimeout.
GMD settings: 0.0 disables checking for delivery timeouts. The value can be any real number 0.0 or greater.
Equivalent C function: TipcMsgSetDeliveryTimeout
TipcMt.setDeliveryTimeout
Set the delivery timeout of a message type.
GMD settings: 0.0 disables checking for delivery timeouts. The value can be any real number 0.0 or greater.
Equivalent C function: TipcMtSetDeliveryTimeout
TipcSrv.gmdFileDelete
Delete guaranteed message delivery files for the connection to RTserver. Useful for deleting any obsolete GMD information.
Equivalent C function: TipcSrvGmdFileDelete
TipcSrv.gmdMsgAck
Acknowledge the delivery of a message.
Equivalent C function: TipcMsgAck
TipcSrv.getGmdNumPending
Get the number of outgoing GMD messages still pending on a connection.
Equivalent C function: TipcSrvGetGmdNumPending

Sending GMD Messages

To send messages with GMD, simply set the message delivery mode to TipcDefs.DELIVERY_SOME or to TipcDefs.DELIVERY_ALL. Send the message as usual with TipcSrv.send.

There are two ways to set the message delivery mode:

Setting the mode to TipcDefs.DELIVERY_SOME means that the guaranteed message must go to at least one subscriber. That is, the sending process only needs to receive an acknowledgment from one receiving process before timing out in order to declare success. It can receive acknowledgments from more than one receiving process.

Setting the mode to TipcDefs.DELIVERY_ALL means that the guaranteed message must go to all the subscribers. That is, the sending process must receive acknowledgments from all the receiving processes before timing out before it can declare success.

For example:

msg.setDeliveryMode(TipcDefs.DELIVERY_ALL); 
srv.send(msg); 

For GMD, TipcSrv.send:

  1. Increments an internal per-connection outgoing sequence number.
  1. Sets the message sequence number to the incremented value.
  2. Saves a copy of the message in the connection GMD area.
  3. Saves the current wall clock time in the GMD area, for detecting a delivery timeout.

Receiving GMD Messages

For GMD, TipcSrv.next recognizes a message resent with GMD and checks if the resent message has a sequence number lower than the highest sequence number already acknowledged from the sending process. The check also handles long-running processes that might overflow and wrap around the four byte sequence number. If the resent message has already been acknowledged, TipcSrv.next acknowledges the message again so that the sender is notified this time of successful delivery.

TipcSrv.next always allows GMD messages that have not been resent to pass through, regardless of their sequence number. This allows flexibility and correct behavior when some processes use TipcSrv.gmdFileDelete and others do not, enabling use of old sequence numbers.

TipcSrv.next also handles GMD_ACK messages directly so that the application code never has to worry about taking care to read and process one GMD_ACK message for each outgoing message sent with GMD. When a GMD_ACK message is received, the corresponding message is removed from the connection GMD area.

Acknowledging GMD Messages

Typically, an application calls TipcSvc.mainLoop and this acknowledges the message (sends a GMD_ACK message).

Also, you can useTipcMsg.ack, which automatically calls TipcSrv.gmdMsgAck to acknowledge the message for GMD. TipcSrv.gmdMsgAck can also be called manually to acknowledge a message. For example:

srv.gmdMsgAck(msg) 

TipcSrv.gmdMsgAck constructs a GMD_ACK message containing the sequence number of the message to be acknowledged and sends the GMD_ACK message through the connection that the message to be acknowledged was received on.

Waiting for Completion of GMD

GMD senders must read messages occasionally to receive the acknowledgments. If a connection process both sends and receives messages at regular intervals, no extra actions are needed because the acknowledgments travel with the normal flow of messages. A short-running or sending-only process can accomplish this by calling TipcSrv.mainLoop or TipcSrv.next before the program exits. A sending process can also check how many outgoing GMD messages are still pending with TipcSrv.getGmdNumPending. This is useful for waiting until all acknowledgments arrive. For example:

System.out.println("Read data until all acknowledgments come in."); 
do { 
  srv.mainLoop(1.0); 
  num_pending=srv.getGmdNumPending(); 
} while (num_pending > 0); 

Example of Using GMD

Here is an example of configuring and using GMD with Java. This example also uses a callback to process GMD failures. See Processing of GMD_FAILURE Messages on page 182 to see the sample code for the callback.

import java.io.*; 
import com.smartsockets.*; 
 
public class gmd_example { 
 
  private static final int SAMPLE = 1001; 
 
/*=============================================================== */ 
  public gmd_example() { 
 
    TipcSrv srv=TipcSvc.getSrv(); 
 
    // set the server names 
    try { 
      Tut.setOption("ss.server_names", "altoids,maple"); 
    } 
    catch (TipcException e) { 
      Tut.fatal(e); 
    } // catch 
 
    // set the unique subject for gmd 
    try { 
      Tut.setOption("ss.unique_subject", "gmd_publisher"); 
    } 
    catch (TipcException e) { 
      Tut.fatal(e); 
    } // catch 
 
    // delete old gmd files 
    try { 
      srv.gmdFileDelete(); 
    } 
    catch (TipcException e) { 
      Tut.fatal(e); 
    } // catch 
 
    // connect to RTserver 
    try { 
      srv.create(); 
    } 
    catch (TipcException e) { 
      Tut.exitFailure("Couldn’t connect to RTserver!"); 
    } // catch 
 
    // get message type for gmd failure message 
    TipcMt mt = TipcSvc.lookupMt(TipcMt.GMD_FAILURE); 
 
    //destroy old gmd callback 
    TipcCb cb = srv.getDefaultGmdFailureCb(); 
    try { 
      srv.removeProcessCb(cb); 
    } 
    catch (TipcException e) { 
      Tut.fatal(e); 
    } // catch 
 
    // setup new callback--callback code is shown later in this chapter 
    gmdFailureMsgCallback pcb = new gmdFailureMsgCallback(); 
    TipcCb pcbh = srv.addProcessCb(pcb, mt, srv); 
    // check the ’handle’ returned for validity 
    if (null == pcbh) { 
      Tut.exitFailure("Couldn’t register gmd failure callback!"); 
    } // if 
 
    // define new message type 
    try { 
      mt = TipcSvc.createMt("SAMPLE", SAMPLE, "str"); 
    } 
    catch (TipcException e) { 
      Tut.exitFailure("Message type already exists!"); 
    } // catch 
 
  // following is a for loop which publishes 3 messages. 
  // assuming that no one subscribes to /sample/gmd and 
  // the option in the RTserver you connect to is set as follows: 
  // setopt zero_recv_failure_option TRUE 
  // each message will result in an immediate gmd failure 
  // and the callback entered for each 
 
    for (int i=1; i <= 3; i++) { 
 
      try { 
        // create a message of type SAMPLE 
        TipcMsg msg = TipcSvc.createMsg(mt); 
        msg.setDest("/sample/gmd");                  // publish to subject 
        msg.setDeliveryMode(TipcDefs.DELIVERY_ALL);  // all receivers to ack 
        msg.setDeliveryTimeout(0.1); 
        msg.addNamedStr("Data", "gmd message #" + i); 
        System.out.println("< sending gmd message #" + i + ">"); 
 
        // send and flush the message 
        srv.send(msg); 
        srv.flush(); 
 
        // call mainloop to read in acknowledgement message 
        srv.mainLoop(2.0); 
      } 
      catch (TipcException e) { 
        Tut.fatal(e); 
      } // catch 
 
    } // for 
 
    //disconnect from the server 
    try { 
      srv.destroy(); 
      srv.removeProcessCb(pcbh);   //unregister the callback 
    } 
    catch (TipcException e) { 
      Tut.exitFailure("unable to disconnect from server"); 
    } // catch 
 
  } // gmd_example (constructor) 
 
  public static void main(String[] argv) { 
    new gmd_example(); 
  } // main 
} // gmd_example class 

TIBCO SmartSockets™ Java Library User’s Guide and Tutorial
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com