Example index

Handling and Logging UMP Receiver Callbacks

Most applications that use Ultra Messaging (UM) are already logging a lot of application specific data. Sometimes, these logs can be as large as multiple gigabytes, per day! So it is understandable that users will want to keep their UM specific items to a minimum and focus on the application logging. That being said, there is some crucial data that should be logged pertaining to the Ultra Messaging Persistence (UMP) framework as, without this data, debugging problems related to messaging can be near impossible. This sample offers you the data that is most important to log, and the reason why this data is so important to track.

There is one program source file:

Program explanation: UMPReceiverCallbacks.cs

Context/Receiver Create

Standard context and receiver creation. Note the message handler function passed into the receiver create function, this is the callback function that will handle all the receiver callback events.

00017                  LBMReceiverCallback myReceiverCallback = new LBMReceiverCallback(onReceive);
00018  
00019                  /*** Initialization: create necessary UM objects. ***/
00020                  ctx = new LBMContext();
00021  
00022                  rtopic = new LBMTopic(ctx, "test.topic");
00023                  rcv = new LBMReceiver(ctx, rtopic, myReceiverCallback, null);

Handle Message Callback

Here is the message callback. The message callback function is a single function that can be coded to deal with many different callback events. Only a single event is processed at a time, therefore a switch statement works best for handling the different types of events that are possible. Below is a description of each event, as well as which data is useful to log, as well as how important it is to log such data in the applications log file.

Message Data Callback (LBM.MSG_DATA)

This is the message type used for handling received messages. If your application is already printing the data from every message, then it would be worth logging the Ultra Messaging sequence number, topic string, and the flags in the message data structure. The sequence number can help us keep track of what messages this particular receiver consumed, the topic will help identify the receiver, and the flags can identify whether the messages are coming directly from a source or being recovered from a store.

If your application is not regularly logging data messages because it would grow the application logs too large, then this data can be skipped. However, it would be useful to have the ability to enable logging as part of some kind of application debug mode.

00036                          case LBM.MSG_DATA:
00037                                  System.Console.Out.Write("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber() + "]");
00038                                  if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) {
00039                                          System.Console.Out.Write("-RX-");
00040                                  }
00041                                  if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) {
00042                                          System.Console.Out.Write("-OTR-");
00043                                  }
00044                                  System.Console.Out.Write(", ");
00045                                  System.Console.Out.WriteLine(msg.data().Length + " bytes");
00046                                  break;

Request Message (LBM.MSG_REQUEST)

Similar to data messages above, the only real difference being that these messages can be responded to via the API.

00047                          case LBM.MSG_REQUEST:
00048                                  if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) {
00049                                          System.Console.Out.Write("-RX-");
00050                                  }
00051                                  if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) {
00052                                          System.Console.Out.Write("-OTR-");
00053                                  }
00054                                  System.Console.Out.Write(", ");
00055                                  System.Console.Out.WriteLine(msg.data().Length + " bytes");
00056                                  break;

Unrecoverable Loss (LBM.MSG_UNRECOVERABLE_LOSS)

This event indicates that a single message has been declared unrecoverable, and will not be received by the application. This should always be logged. Unrecoverable Loss in a UMP environment is typically not expected and indicates a failure of the transport level recovery, so this event should be logged every time, with the topic name, the sequence number provided, and the source information. The source information will identify the source publishing the messages that have been lost.

00063                          case LBM.MSG_UNRECOVERABLE_LOSS:
00064                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber().ToString("x") + "], LOST");
00065                                  break;

Unrecoverable Loss Burst (LBM.MSG_UNRECOVERABLE_LOSS_BURST)

Similar to regular loss, but indicates a larger gap of messages have been decalred unrecoverable. Same as above, this should always be logged. Since this indicates a large number of messages that are unrecoverable, it is even more important to log all the data provided in the message data structure (topic name, sequence number, and source information). See sample handle_burst for more information on handling burst loss

00066                          case LBM.MSG_UNRECOVERABLE_LOSS_BURST:
00067                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber().ToString("x") + "], LOST BURST");
00068                                  break;

Beginning of Transport Session (LBM.MSG_BOS)

BOS indicates that a new transport session has been detected in which messages will be received on for a specific source transport. This callback should be logged, as it is useful when trying to debug connectivity issues. This should always be logged with the topic name and source information.

00057                          case LBM.MSG_BOS:
00058                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "], Beginning of Transport Session");
00059                                  break;

End of Transport Session (LBM.MSG_EOS)

Similar as BOS, this indicates that there has been no activity on a transport and that the transport has timed out. This should always be logged with the same information as BOS.

00060                          case LBM.MSG_EOS:
00061                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "], End of Transport Session");
00062                                  break;

No Source Notification (LBM.MSG_NO_SOURCE_NOTIFICATION)

The no source notifcation callback is not enabled by default, and must be configured with resolution_no_source_notification_threshold . For more information on setting this callback, please see sample: no_source_notify. Logging this callback is entirely up to the developer, however it could also be useful when trying to debug connectivity issues.

00069  

UMP Registration Error (LBM.MSG_UME_REGISTRATION_ERROR)

This callback event indicates an error while trying to register with a UMP store. This should be logged every time along with the topic name and error string provided in the callback.

00070                          case LBM.MSG_UME_REGISTRATION_ERROR:
00071                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration error: " + msg.dataString());
00072                                  break;

UMP Registration Success (LBM.MSG_UME_REGISTRATION_SUCCESS_EX)

This callback is executed every time the receiver registers to a particular store, and very much is worth logging. In particular, the topic name, store information, receiver and source RegID.s, flags, and registered sequence number. The sequence number here indicates where the store thinks this receiver is at, and is one of the deciding factors when determining the starting sequence number for the receiver. The source and receiver RegID are useful for tracking those components in the store log and store web-monitor.

00073                          case LBM.MSG_UME_REGISTRATION_SUCCESS_EX:
00074                                  UMERegistrationSuccessInfo reg = msg.registrationSuccessInfo();
00075                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] store " + reg.storeIndex() + ": "
00076                                          + reg.store() + " UME registration successful. Sequence number is " + reg.sequenceNumber());
00077                                  break;

UMP Registration Complete (LBM.MSG_UME_REGISTRATION_COMPLETE_EX)

This callback is only executed once per registration, regardless of the number of stores. Complete indicates that a quorum of stores has been registered, and the receiver is ready to start receiving messages. It is important to log the topic name, the source and receiver RegID.s, flags, and the consensus sequence number . as this is the first sequence number the receiver should consume going forward.

00078                          case LBM.MSG_UME_REGISTRATION_COMPLETE_EX:
00079                                  UMERegistrationCompleteInfo regcomplete = msg.registrationCompleteInfo();
00080                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration complete. SQN "
00081                                          + regcomplete.sequenceNumber() + ". Flags " + regcomplete.flags());
00082                                  break;

UMP Deregistration Success (LBM.MSG_UME_DEREGISTRATION_SUCCESS_EX)

This callback should be logged when using the Receiver Paced Persistence mode of operation or when using the deregistration AP. It indicates that the receiver deregistered from a particular store. The source and receiver RegID, sequence number, store information, and flags should be logged here.

00083                          case LBM.MSG_UME_DEREGISTRATION_SUCCESS_EX:
00084                                  System.Console.Out.Write("DEREGISTRATION SUCCESSFUL ");
00085                                  UMEDeregistrationSuccessInfo dereg = msg.deregistrationSuccessInfo();
00086                                  System.Console.Out.Write("[" + msg.topicName() + "][" + msg.source() + "] store " + dereg.storeIndex() + ": "
00087                                          + dereg.store() + " UME deregistration successful. SrcRegID " + dereg.sourceRegistrationId() + " RcvRegID " + dereg.receiverRegistrationId()
00088                                          + ". Flags " + dereg.flags() + " ");
00089                                  System.Console.Out.WriteLine();
00090                                  break;

UMP Deregistration Complete (LBM.MSG_UME_DEREGISTRATION_COMPLETE_EX)

.Similar to the deregistration success callback; this callback indicates that the receiver has successfully deregistered from all stores, and should be logged. Topic name and source information are sufficient for this callback.

00091                          case LBM.MSG_UME_DEREGISTRATION_COMPLETE_EX:
00092                                  System.Console.Out.WriteLine("DEREGISTRATION COMPLETE");
00093                                  break;

UMP Registration Change (LBM.MSG_UME_REGISTRATION_CHANGE)

This callback should be logged as it indicates a change in the registration status for a particular topic. Topic name, source information, and the message data should be printed here. The message data will have the change that has been made to registration.

00094                          case LBM.MSG_UME_REGISTRATION_CHANGE:
00095                                  System.Console.Out.WriteLine("[" + msg.topicName() + "][" + msg.source() + "] UME registration change: " + msg.dataString());
00096                                  break;

Other

Lastly, it is a good idea to have a default case to log anything that the application is not expecting. As of writing this sample, there are no other callbacks that could be handled for UMP. However, new callbacks are added, so it's good in the event of a library upgrade.

00097                          default:
00098                                  System.Console.Out.WriteLine("Other event, type=" + msg.type());
00099                                  break;