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.
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.
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:
For GMD, TipcSrv.send:
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.
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:
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.
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);
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 |