Sun Microsystems
Products & Services
 
Support & Training
 
 

Previous Previous     Contents     Index     Next Next

22.3.3 Agent-Side Buffering

In pull mode, notifications are stored by the connector server in a buffer until they are pulled by the connector client. Any one of the pull operations, whether on-demand or periodic, empties this buffer, and it fills up again as new notifications are triggered.

By default, this buffer will grow to contain all notifications. The ClientNotificationHandler interface defines the static NO_CACHE_LIMIT field to represent an unlimited buffer size. If the notifications are allowed to accumulate indefinitely in the cache, this can lead either to an "out of memory" error in the agent application, a saturation of the communication layer, or an overload of the manager's listeners when the notifications are finally pulled.

To change the size of the agent's cache, call the connector client's setCacheSize method. The size of the cache is expressed as the number of notifications that can be stored in its buffer. When a cache buffer of limited size is full, new notifications will overflow and be lost. Therefore, you should also choose an overflow mode when using a limited cache size. The two overflow modes are defined by static fields of the ClientNotificationHandler interface:

  • DISCARD_OLD: The oldest notifications will be lost and the buffer will always be renewed with the latest notifications that have been triggered. This is the default value when a limit is first set for the cache size.

  • DISCARD_NEW: Once the notification buffer is full, any new notifications will be lost until the buffer is emptied by forwarding the messages. The buffer will always contain the first notifications triggered after the previous pull operation.

We demonstrate each of these modes in our sample manager, first by setting the cache size and the overflow mode, then by triggering more notifications than the cache buffer can hold.

Example 22-7 Controlling the Agent-Side Buffer

System.out.println(">>> Use pull mode with period set to zero, " +
    "buffer size set to 10, and overflow mode set to DISCARD_OLD.");
connectorClient.setMode(ClientNotificationHandler.PULL_MODE);
connectorClient.setPeriod(0);
connectorClient.setCacheSize(10, true); // see "Buffering Specifics"
connectorClient.setOverflowMode(ClientNotificationHandler.DISCARD_OLD);

System.out.println(">>> Have our MBean broadcast 30 notifications...");
params[0] = new Integer(30);
signatures[0] = "java.lang.Integer";
connectorClient.invoke(mbean, "sendNotifications", params, signatures);
System.out.println(">>> Done.");

// Call getNotifications to pull all buffered notifications from the agent
System.out.println("\n>>> Press Enter to get notifications.");
System.in.read();
connectorClient.getNotifications();

// Wait for the handler to process the 10 notifications
// These should be the 10 most recent notifications
// (the greatest sequence numbers)
Thread.sleep(100);
System.out.println("\n>>> Press Enter to continue.");
System.in.read();

// We should see that the 20 other notifications overflowed the agent buffer
System.out.println(">>> Get overflow count = " +
    connectorClient.getOverflowCount());

The overflow count gives the total number of notifications that have been discarded because the buffer has overflowed. The number is cumulative from the first manger-side listener registration until all of the manager's listeners have been unregistered. The manager application can modify or reset this value by calling the setOverflowCount method.

In our example application, we repeat the actions above, to cause the buffer to overflow again, but this time using the DISCARD_NEW policy. Again, the buffer size is ten and there are thirty notifications. In this mode, the first ten sequence numbers remain in the cache to be forwarded when the manager pulls them from the agent, and twenty more will overflow.

22.3.3.1 Buffering Specifics

When the buffer is full and notifications need to be discarded, the time reference for applying the overflow mode is the order in which notifications have arrived in the buffer. Neither the time stamps nor the sequence numbers of the notifications are considered, because neither of these are necessarily absolute; even the sequence of notifications from the same broadcaster can be non-deterministic. And in any case, broadcasters are free to set both time stamps and sequence numbers as they see fit, or even to make them null.

The second parameter of the setCacheSize method is a boolean that determines whether or not the potential overflow of the cache is discarded when reducing the cache size. If the currently buffered notifications do not fit into the new cache size and this parameter is true, excess notifications are discarded according to the current overflow mode. The overflow count is also updated accordingly.

In the same situation with the parameter set to false, the cache will not be resized. You need to check the return value of the method when you set this parameter to false. If the cache cannot be resized because it would lead to discarded notifications, you need to empty the cache and try resizing the cache size again. To empty the cache, you can either pull the buffered notifications with the getNotifications method or discard them all by calling the connector client's clearCache method.

When the existing notifications fit within the new cache size or when increasing the cache size, the second parameter of setCacheSize has no effect.

Because several managers can connect through the same connector server object, it must handle the notifications for each separately. This implies that each connected manager has its own notification buffer and its own settings for controlling this cache. The overflow count is specific to each manager as well.

22.3.3.2 Buffering Generalities

Here we have demonstrated each setting of the forwarding mechanism independently by controlling the notification broadcaster. In practice, periodic pulling, agent-side buffering and buffer overflow can all be happening at once. And you can call getNotifications at any time to do an on-demand pull of the notifications in the agent-side buffer. You should adjust the settings to fit the known or predicted behavior of your management architecture, depending upon communication constraints and your acceptable notification loss rate.

The caching policy is completely determined by the manager application. If notification loss is unacceptable, it is the manager's responsibility to configure the mechanism so that they are pulled as often as necessary. Also, the legacy notification mechanism can be updated dynamically. For example, the manager can compute the notification emission rate and update any of the settings (buffer size, pull period, and overflow mode) to minimize the risk of a lost notification.

22.4 Running the Legacy Notification Forwarding Example

The examplesDir/legacy/Notification directory contains all of the files for the broadcaster MBean, the BaseAgent application, and our Client application that is the listener object. To run the legacy notification forwarding example, we use the BaseAgent application that contains an RMI connector server.

ProcedureTo Run the Legacy Notification Forwarding Example

  1. Compile all files in this directory with the javac command.

    For example, on the Solaris platform with the Korn shell, type:

    $ cd examplesDir/legacy/Notification/
    $ javac -classpath classpath *.java

  2. Start the agent on another host or in another terminal window with the following command.

    Be sure that the classes for the NotificationEmitter MBean can be found in its classpath:

    $ java -classpath classpath BaseAgent

  3. Wait for the agent to be completely initialized, then start the manager in another window with the following command, where hostname is the name of the host running the agent.

    If you started the agent on the same host, you can omit the hostname:

    $ java -classpath classpath Client hostname

    When started, the manager application first creates the NotificationEmitter MBean and then registers itself as a listener.

  4. Press Enter when the application pauses to step through the various notification forwarding situations that we have seen in this topic.

  5. Press Enter again in the manager window to exit the application.

    Leave the agent application running if you want to interact with the example through the HTML protocol adaptor of the BaseAgent.

ProcedureTo Interact With the Legacy Notification Forwarding Mechanism

  1. Start the manager in another window with the following command, where hostname is the name of the host running the agent.

    If you started the agent on the same host, you can omit the hostname:

    $ java -classpath classpath Client hostname

  2. Load the following URL in your browser and go to the MBean view of the NotificationEmitter MBean:

    http://hostname:8082/

    If you get an error, you might have to switch off proxies in your browser preference settings. Any browser on your local network can also connect to this agent using this URL.

  3. When the manager application pauses for the first time, call the sendNotifications method from your browser with a small integer as the parameter.

    The listener handles your notifications in the manager's terminal window. Because the manager is still in push mode, they are forwarded immediately.

  4. Press Enter in the manager window.

    The manager is now in pull mode with a pull period of 500 milliseconds.

  5. Through the MBean view, send 1000 notifications.

    If your agent's host is slow enough, or if your manager's host is fast enough, you might be able to see the manager pause briefly after it has processed all notifications from one period and before the next ones are forwarded.

  6. Press Enter in the manager window.

    The agent now forwards notifications by request.

  7. Through the MBean view, send 15 notifications, then press Enter again.

    The manager pulls all of the notifications: the 30 triggered by the manager and the 15 we just triggered. They were all kept in the buffer, waiting for the manager's request to forward them. Remember that the sendNotifications operation resets the sequence numbering every time it is invoked.

  8. Press Enter in the manager's window.

    The cache size is set to 10 notifications and the overflow mode to DISCARD_OLD.

  9. Through the MBean view, send 15 more notifications, then press Enter again.

    Only the last 10 of our notifications fit into the cache buffer. All the rest, including those already triggered by the manager, overflow and are discarded.

  10. Press Enter to see that the discarded notifications are tallied in the overflow count.

  11. Press Enter in the manager's window.

    The cache size is still 10 notifications and the overflow mode is set to DISCARD_NEW.

  12. Through the MBean view, send only 5 more notifications, then press Enter again.

    The first 10 of the manager-triggered notifications are received. All of the more recent notifications, including ours, overflow the cache buffer and are lost.

  13. Press Enter to see that the lost notifications are tallied in the overflow count:

    35 from Step 12 plus 25 more from this step, for a total of 60.

  14. Press Enter in the manager's window again to stop the Client application.

  15. Press Enter in the other window to stop the agent application when you have finished running the example.

Previous Previous     Contents     Index     Next Next