Example index

Handling Burst Loss / Determining Size of Burst

Burst loss is an Ultra Messaging concept that deals with large amount of message fragments that have been detected as loss on a given transport. Typically in a UM application, when a single message fragment is detected loss and not recovered within the configured transport timeout window, that message fragment is declared unrecoverable loss. In the event of a very large fragment gap, the loss could be declared unrecoverable much sooner if the size of the gap exceeds the threshold configured by the receiver attribute delivery_control_maximum_burst_loss - default is 512 message fragments.

The key thing about burst loss is that the size of the burst is not necessarily equal to that of the configured threshold, in fact the burst is very likely much larger than the threshold. The threshold acts more as a maximum threshold in which the receiver is willing to accept before giving up. The event itself does not provide the size of the burst though, it is the applications responsibility to capture that data if it is necessary, and that is the purpose of this sample application, to demonstrate how to calculate the size of the burst.

Calculating the size of the burst is quite easy. The burst event callback does provide a sequence number which is the high sequence number of the burst. If the application simply tracks the previously consumed sequence number, it can subtract that from the sequence number in the burst event to know exactly how many message fragments are included in the burst. To successfully track the last sequence number, the application will simply need to record the last sequence number received in the message callback, unrecoverable loss callback, and the burst callback itself, as these are the only three callbacks that will advance the sequence number.

Note: As always, sequence numbers are assigned to message fragments, which may or may not be equal to one whole application message. If an application level message exceeds the configurable UM datagram size, than a single message may take up multiple message fragments, which would span over multiple sequence numbers.

There is one program source file:

Program explanation: HandleBurst.java

Context and Receiver Creation

Standard context and receiver creation, with a minimal amount of options set:

00018          /* Initialize and create receiver and receiver callback */
00019                  ReceiverCallback myReceiverCallback = new ReceiverCallback();
00020  
00021          ctx = new LBMContext();
00022          rcv_attr = new LBMReceiverAttributes();
00023  
00024          rtopic = new LBMTopic(ctx, "test.topic", rcv_attr);
00025          rcv = new LBMReceiver(ctx, rtopic, myReceiverCallback, null);

Receiver Message Callback

Here in the message callback, the sample application focuses on thress particular events:

  1. Data - This is the event that executes when the application receives a data message
  2. Loss - This is the event that executes when a single message fragment becomes unrecoverable loss
  3. Loss Burst - This is the event that executes when a burst of message fragments becomes unrecoverable loss.

First the message callback. This is where the application would typically process the data inside a message, or maybe retain the message to be processed later on a spearate thread. In either case, the last sequence number should be updated here:

00039                  case LBM.MSG_DATA:
00040                      lastSqn = msg.sequenceNumber();
00041                      break;

Next is the unrecoverable loss event, which indicates that a single message fragment has become unrecoverable. The sequence number provided in this event is the message fragment that is unrecoverable, so it should set the last sequence number variable here as well:

00042                  case LBM.MSG_UNRECOVERABLE_LOSS:
00043                      lastSqn = msg.sequenceNumber();
00044                      break;

Finally the burst event callback. Here we can calculate the size of the burst my subtracting the last sequence number from the sequence number provided in the callback itself. Once the burst size has been calculated, update the last sequence number as well, because the very next could be another burst loss event, and the application will want to calculate the size of that burst as well:

00045                  case LBM.MSG_UNRECOVERABLE_LOSS_BURST:
00046                      long burst = lastSqn - msg.sequenceNumber();
00047                      System.out.println("WARNING: Burst loss of " + burst + " messages!");
00048                      lastSqn = msg.sequenceNumber();
00049                      break;