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.java

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.

00014          ReceiverCallback myReceiverCallback = new ReceiverCallback();
00015  
00016          /*** Initialization: create necessary UM objects. ***/
00017          ctx = new LBMContext();
00018  
00019          rtopic = new LBMTopic(ctx, "test.topic");
00020          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.

00034                  case LBM.MSG_DATA:
00035                      System.out.print("[" + msg.topicName() + "][" + msg.source() + "][" + msg.sequenceNumber() + "]");
00036                      if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) {
00037                          System.out.print("-RX-");
00038                      }
00039                      if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) {
00040                          System.out.print("-OTR-");
00041                      }
00042                      System.out.print(", ");
00043                      System.out.println(msg.data().length + " bytes");
00044                      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.

00045                  case LBM.MSG_REQUEST:
00046                      if ((msg.flags() & LBM.MSG_FLAG_UME_RETRANSMIT) != 0) {
00047                                                  System.out.print("-RX-");
00048                                          }
00049                                          if ((msg.flags() & LBM.MSG_FLAG_OTR) != 0) {
00050                                                  System.out.print("-OTR-");
00051                                          }
00052                                          System.out.print(", ");
00053                                          System.out.println(msg.data().length + " bytes");
00054                                          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.

00061                  case LBM.MSG_UNRECOVERABLE_LOSS:
00062                      System.err.println("[" + msg.topicName() + "][" + msg.source() + "][" + Long.toHexString(msg.sequenceNumber()) + "], LOST");
00063                      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

00064                  case LBM.MSG_UNRECOVERABLE_LOSS_BURST:
00065                      System.err.println("[" + msg.topicName() + "][" + msg.source() + "][" + Long.toHexString(msg.sequenceNumber()) + "], LOST BURST");
00066                      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.

00055                  case LBM.MSG_BOS:
00056                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "], Beginning of Transport Session");
00057                      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.

00058                  case LBM.MSG_EOS:
00059                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "], End of Transport Session");
00060                      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.

00067  

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.

00068                  case LBM.MSG_UME_REGISTRATION_ERROR:
00069                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration error: " + msg.dataString());
00070                      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.

00071                  case LBM.MSG_UME_REGISTRATION_SUCCESS_EX:
00072                      UMERegistrationSuccessInfo reg = msg.registrationSuccessInfo();
00073                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "] store " + reg.storeIndex() + ": "
00074                          + reg.store() + " UME registration successful. Sequence number is " + reg.sequenceNumber());
00075                      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.

00076                  case LBM.MSG_UME_REGISTRATION_COMPLETE_EX:
00077                      UMERegistrationCompleteInfo regcomplete = msg.registrationCompleteInfo();
00078                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration complete. SQN " 
00079                          + regcomplete.sequenceNumber() + ". Flags " + regcomplete.flags());
00080                      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.

00081                  case LBM.MSG_UME_DEREGISTRATION_SUCCESS_EX:
00082                      System.out.print("DEREGISTRATION SUCCESSFUL ");
00083                      UMEDeregistrationSuccessInfo dereg = msg.deregistrationSuccessInfo();
00084                      System.out.print("[" + msg.topicName() + "][" + msg.source() + "] store " + dereg.storeIndex() + ": "
00085                          + dereg.store() + " UME deregistration successful. SrcRegID " + dereg.sourceRegistrationId() + " RcvRegID " + dereg.receiverRegistrationId()
00086                          + ". Flags " + dereg.flags() + " ");
00087                      System.out.println();
00088                      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.

00089                  case LBM.MSG_UME_DEREGISTRATION_COMPLETE_EX:
00090                      System.out.println("DEREGISTRATION COMPLETE");
00091                      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.

00092                  case LBM.MSG_UME_REGISTRATION_CHANGE:
00093                      System.out.println("[" + msg.topicName() + "][" + msg.source() + "] UME registration change: " + msg.dataString());
00094                      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.

00095                  default:
00096                      System.out.println("Other event, type=" + msg.type());
00097                      break;