Universal Messaging 9.9 | Universal Messaging Concepts | Commonly Used Features | Named Objects and Shared Named Objects
 
Named Objects and Shared Named Objects
Universal Messaging provides the ability for the server to maintain state for the last event that was consumed by a consumer on a channel. By providing a unique name, you can create a so-called named object on a channel. Then, even if your application is stopped and restarted, you will only consume available events from the last event ID that the server stored as successfully consumed by that named object.
When using normal named objects (as opposed to shared named objects, see below for description), there is only one store of events and that is the channel itself. Each event remains on the channel until all named objects have consumed (and acknowledged) that event, and then the event is removed from the channel.
Named objects can be persistent, i.e. the last event ID is written to disk, so that if the Universal Messaging Realm Server is restarted, the last event ID consumed is retrievable for each named object on a channel.
Background to using Named Objects
A UM channel (in JMS terminology this would be a "topic") can have several different "engines", one of which is the JMS engine. The JMS engine means that the channel will only store events whilst they are required by a consumer. So if you have a slow synchronous consumer, the channel will store the events until they are pulled off. If you have a named object, the channel will store the events until they are acknowledged. If you use the normal fanout engine, the events will remain on the channel regardless of any named objects. Only capacity or TTL or purges will delete events.
One reason for using named objects is to facilitate recovery if a consumer is terminated. For example, if the consumer crashes or you turn off the computer and start up another one, the server will remember where that consumer finished off because it stored the event ID on the named object.
Comparison of Named Objects and Shared Named Objects
Normally, UM maintains a store of events for each named object (known in JMS as a "durable subscription") until a consumer has received the events. When the consumer informs UM that it has received a certain event from the store, UM deletes this event from the store and all other events in the store that have a lower event ID (i.e. were created at an earlier time). There can be no more than 1 consumer of a given named object at any time; if a consumer tries to access a named object that is already being accessed by another consumer, an error will be returned to the second consumer.
There are some cases in which it may be desirable for two or more consumers to access a named object at the same time. UM offers a variation of a named object known as a shared named object.
A shared named object allows multiple consumers to access the same named object. UM delivers events to the consumers in round-robin fashion. So, for example, if there are 10 events in the named object and two consumers who share the named object, then UM will deliver events 1, 3, 5, 7, 9 to the first consumer and events 2, 4, 6, 8, 10 to the second consumer.
A typical use case is load balancing, where multiple servers are available to process a stream of events.
As for normal named objects, you can specify that the shared named object is "persistent" and/or "cluster wide". If the shared named object is persistent, UM will retain it if there is a system restart. If the shared named object is cluster wide and it exists on a cluster wide channel, the named object will also be replicated across the cluster.
Storage Considerations
There are some storage considerations to be aware of when using shared named objects as opposed to normal (i.e. non-shared) named objects.
When you define a shared named object, UM maintains a copy of all of the events of the named object in an internal store. The copies remain in the internal store until the original events have been accessed by the consumer. The benefit for the consumer is that events are held until the consumer is ready to receive them.
If the consumer accesses the events using event filtering, some events are never selected, and therefore the copies of these events remain in the internal store. As mentioned earlier, when an event is consumed for a normal named object, all earlier events are also removed; however, for a shared named object, only the consumed event is removed from the store. This is by design, and can, in time, lead to UM retaining large numbers of events that are never used. If you have made the shared named object persistent, a copy of the internal store will be maintained on disk, and this disk copy will also contain copies of the events that are not used.
In order to delete messages from the internal store you can purge events from the channel that the named object is created on. That purge will also flow through to the internal store.
You can also use the setting of the UM global parameter SharedDurableFilterBound to limit the set of events that are copied to the internal store for a given shared named object. If you set the value of this parameter to "true", the following behavior will be activated:
*When the first consumer connects to the shared named object and specifies an event filter, then only events that match the filter will be copied to the internal store.
*If a second consumer connects to the same shared named object and also specifies an event filter, then from that time onwards, only events matching the second filter will be copied to the internal store. The first consumer still uses its filter to take events off the internal store.
*If the second consumer specifies no event filter, the filter of the first consumer remains in effect for copying events to the internal store.
*If the second consumer specifies a different filter than the first consumer, the first consumer will receive an asynchronous exception.
You can use the API method getSharedNamedObjectOutstandingEvents() on nNamedObject to get the number of events that are outstanding for the shared durable, i.e. the number of messages that have not yet been acknowledged by the shared durable and are therefore residing on the server. If you call this method on a non-shared durable, it will return the value -1.
In general, unless you really need to use shared named objects, we suggest you use normal named objects instead.

Copyright © 2013-2015 | Software AG, Darmstadt, Germany and/or Software AG USA, Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors.
Innovation Release