Guaranteed Message Delivery (GMD)


TIBCO SmartSockets includes the capability to guarantee message delivery. This ensures reliability even in the face of network or system failures and eliminates the need to write complex error recovery code. Figure 11 illustrates the successful processing of a guaranteed message.

Figure 11 Steps Involved in Successful GMD

  1. The message is saved to the GMD area, which is written to a recoverable disk-based queue for file-based GMD and written to a recoverable queue in memory for memory-based GMD.
  1. The sending program sends the message to RTserver.
  2. RTserver forwards the message to all intended recipients. For simplicity, the diagram shows only one receiver.
  3. After processing, a persistent file in the receiver’s GMD area containing a highest sequence number (HSN) is updated. The highest sequence number is used to ensure a given receiver does not process a message more than once, even if it is resent by the sender.
  4. After the receiving program reads and processes the message, TIBCO SmartSockets transparently sends an acknowledgment. (This acknowledgment is typically sent automatically when the message is destroyed, but it can also be sent manually using TipcMsgAck.)
  5. RTserver collects the acknowledgments returned from each receiver and sends one acknowledgment back to the sender.
  6. When the sender receives the acknowledgment, it deletes the message from its recoverable queue, shown as the GMD area.

If the sender does not get an acknowledgment within a specified time period, the message can be resent.

It is very simple to change the sending program used at the beginning of this lesson to make use of guaranteed message delivery.

Step 25

Edit the send.c program

Edit send.c to add this line of code before the while loop:

TipcMtSetDeliveryMode(TipcMtLookupByNum(MSG_COUNT),                              
T_IPC_DELIVERY_ALL); 

The call to TipcMtSetDeliveryMode sets the delivery mode message property on all messages of type MSG_COUNT. You can also specify the delivery mode on a per-message basis by using the function TipcMsgSetDeliveryMode. The delivery mode T_IPC_DELIVERY_ALL is used to guarantee that the message arrives at all receivers. Other delivery modes are described in Delivery Mode in Chapter 2, Messages, of the TIBCO SmartSockets User’s Guide.

Step 26

Set the Server_Disconnect_Mode

Set the Server_Disconnect_Mode option of the receiving program you used earlier in this lesson. The easiest way to do this is to modify the receive.cm file that is read in by the program. Add this line to the end of this file:

setopt Server_Disconnect_Mode warm 

These are the only changes needed to guarantee message delivery — you can use the default values for other options that affect GMD. For example, the default value for the Ipc_Gmd_Type option causes file-based GMD to be attempted, and if that is unsuccessful, TIBCO SmartSockets reverts to memory-based GMD.

For more information on all the options that affect GMD and using them to configure GMD, see the TIBCO SmartSockets User’s Guide.

Step 27

Compile, link, and start the revised sending program

After you have made the change to send.c, rebuild the program.

Step 28

Start the receiving program

Start the receiving program:

UNIX:
$ receive.x 
OpenVMS:
$ run receive 
Windows:
$ receive 

If RTserver was not previously running, it is started automatically.

Step 29

Start the edited sending program

With RTserver and the receiving program running, start the sending program in a different window:

UNIX:
$ send.x 
OpenVMS:
$ run send 
Windows:
$ send 

As in the earlier exercises, the sending and receiving programs print a line of output for each message processed. To test GMD, a network failure must be simulated.

Step 30

Stop the receiving program

Go to the window running the receiving program and stop it by typing Ctrl-c. Wait a few seconds, and then restart it using the command shown above. Notice that when the receiving program came back up, it received all the messages that had been sent while it was down.

Step 31

Stop the RTserver

Go to another window and stop the RTserver with this command:

$ rtserver -stop 

As you saw earlier, RTserver restarts automatically when the sender tries to send a message. When RTserver comes back, the sender automatically resends any messages that have not arrived at the receiver. You are able to verify by the message counts in the receiver’s output that the receiver has received all messages.

Setting the Delivery Timeout on a Message

Guaranteed messages can be given a time-to-live by setting their delivery timeout message property using the function TipcMsgSetDeliveryTimeout(msg, timeout). If a guaranteed message is not acknowledged within the amount of time specified by timeout, a GMD_FAILURE message is sent to the sender to notify it of this problem. See TipcMsgSetDeliveryTimeout in the TIBCO SmartSockets Application Programming Interface reference for more details.

If the delivery timeout message property is not explicitly set, the value defaults to the setting of the RTclient option Server_Delivery_Timeout. If this option is not set, the default value is 30 seconds.

Step 32

Stop the receiving program

Go to the window running the receiving program and stop it by typing Ctrl-c. If the receiving program is down for an extended period of time, the sending program begins to print a message for each guaranteed message that was not acknowledged within the timeout interval:

WARNING: Guaranteed message delivery failed (error code 
T_ERR_GMD_SENDER_TIMEOUT) on the connection 
<client:local:_node:RTSERVER>. 
WARNING: The message was originally sent at 17:31:24. 
WARNING: Did not receive acknowledgment within 30 seconds for the 
following guaranteed message: 
type = msg_count 
sender = </lesson6/send> 
dest = </tutorial/lesson6> 
max = 8 
size = 8 
current = 0 
read_only = true 
priority = 0 
delivery_mode = all 
ref_count = 1 
seq_num = 2091 
resend_mode = false 
user_prop = 0 
delivery_timeout = 30 
data (num_fields = 1): 
    int4 5 

This is the default action taken when the message delivery timeout is exceeded. You can override this behavior by defining your own GMD_FAILURE callback. In this callback, you have the ability to:

For more details on GMD see the guaranteed message delivery section in the connections chapter of the TIBCO SmartSockets User’s Guide.

Checking the Delivery Status of a Message

When a message is guaranteed, its status can be checked at any time using the TipcSrvGmdMsgStatus function. TipcSrvGmdMsgStatus polls for the current GMD status of a message by sending a GMD_STATUS_CALL request to RTserver. RTserver responds by sending back a GMD_STATUS_RESULT message that contains a list of RTclients that have successfully acknowledged the message, as well as a list where GMD failed. You can use functions such as TipcSrvMsgSearchType to get the response. TipcSrvGmdMsgStatus is usually only used from a GMD_FAILURE process callback, but it can be called at any time by advanced applications that wish to poll for GMD status.

When RTserver routes a message for GMD, it keeps track of which RTclients should receive the message and the status of GMD to each of these RTclients. The GMD_STATUS_RESULT message contains these four fields:

See TipcSrvGmdMsgStatus in the TIBCO SmartSockets Application Programming Interface reference for more information on checking on the status of message delivery.


TIBCO SmartSockets™ Tutorial
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com