Universal Messaging 10.3 | Developer Guide | Enterprise APIs | Enterprise Developer's Guide for Java | Publish / Subscribe Using Channels/Topics | Using Durable Subscriptions
 
Using Durable Subscriptions
Universal Messaging provides the ability for both asynchronous and synchronous consumers to be durable. A durable subscription allows state to be kept at the server with regard to what events have been consumed by a specific consumer of data.
Asynchronous Durable Consumer
An example of how to create a durable subscription that begins from event ID 0, is persistent and is used in conjunction with an asynchronous event consumer:

public class mySubscriber implements nEventListener {
public mySubscriber() throws Exception {

// construct your session and channel objects here.
// create the durable subscription and begin consuming events from
// the channel at event id 0, i.e. the beginning of the channel

nDurableAttributes.nDurableType type =
nDurableAttributes.nDurableType.Named;
nDurableAttributes attr = nDurableAttributes.create(type, "unique1");

attr.setPersistent(true);
attr.setClustered(false);
attr.setStartEID(0);

nDurable named = myChannel.getDurableManager().add(attr);


myChannel.addSubscriber(this , nobj);
}

public void go(nConsumeEvent event) {
System.out.println("Consumed event "+event.getEventID());
}

public static void main(String[] args) {
new mySubscriber();
}
}
Synchronous Durable Consumer
An example of how to create a durable subscription that begins from event ID 0, is persistent and is used in conjunction with a synchronous event consumer:

public class myIterator {

nChannelIterator iterator = null;

public myIterator() throws Exception {

// construct your session and channel objects here
// create the durable subscription and begin consuming events from the channel
// at event id 0, i.e. the beginning of the channel

nDurableAttributes.nDurableType type =
nDurableAttributes.nDurableType.Named;
nDurableAttributes attr = nDurableAttributes.create(type, "unique2");

attr.setPersistent(true);
attr.setClustered(false);
attr.setStartEID(0);

nDurable named = myChannel.getDurableManager().add(attr);

iterator = myChannel.createIterator(named);
}

public void start() {
while (true) {
nConsumeEvent event = iterator.getNext();
go(event);
}
}

public void go(nConsumeEvent event) {
System.out.println("Consumed event "+event.getEventID());
}

public static void main(String[] args) {
myIterator itr = new myIterator();
itr.start();
}
Both synchronous and asynchronous channel consumers allow message selectors to be used in conjunction with durable subscriptions. Please see the API documentation for more information.
There are also different ways in which events consumed by named consumers can be acknowledged. By specifying that 'auto acknowledge' is true when constructing either the synchronous or asynchronous consumers, then each event is acknowledged as consumed automatically. If 'auto acknowledge' is set to false, then each event consumed has to be acknowledged by calling the ack() method:

public void go(nConsumeEvent event) {
System.out.println("Consumed event "+event.getEventID());
event.ack();
}
Shared Durable Consumer
Multiple subscribers can hold a subscription to the same durable and all the subscribers will process events in a round-robin manner.
nDurableAttributes.nDurableType type =
nDurableAttributes.nDurableType.Shared;

nDurableAttributes attr = nDurableAttributes.create(type, "shared durable");

attr.setPersistent(persistent);
attr.setClustered(isClusterWide);
attr.setStartEID(startEid);

nDurable shared = channels.getDurableManager().add(attr);
Serial Durable Consumer
Multiple subscribers can hold a subscription to the same durable and all the subscribers will process events in a serial manner.
nDurableAttributes.nDurableType type =
nDurableAttributes.nDurableType.Serial;

nDurableAttributes attr = nDurableAttributes.create(type, "serial durable");

attr.setPersistent(persistent);
attr.setClustered(isClusterWide);
attr.setStartEID(startEid);

nDurable serial = channels.getDurableManager().add(attr);
Priority
Two subscribers can hold a subscription to the same durable. One is given priority and will process events during normal operation. If, however, the subscriber with priority is disconnected for whatever reason, and is unable to process events, the second subscriber to that durable will take over and continue to process events as they come in. This allows failover, with backup subscribers handling events if the subscriber with priority goes down.
To do this, we simply create the subscriber with a boolean specifying if this subscriber has priority. Only one subscriber is allowed priority at any given time. An example of a durable subscription specifying priority is shown below:

nDurableAttributes.nDurableType type =
nDurableAttributes.nDurableType.Priority;

nDurableAttributes attr =
nDurableAttributes.create(type, "priority durable");

attr.setPersistent(persistent);
attr.setClustered(isClusterWide);
attr.setStartEID(startEid);

nDurable named = channels.getDurableManager().add(attr);