Enqueue client, when to detect when connection is lost for reconnection?

Enqueue client, when to detect when connection is lost for reconnection?

book

Article ID: KB0075732

calendar_today

Updated On:

Products Versions
TIBCO Streaming 7.x

Description

If the server is shutdown and there is an attempt to enqueue, the first enqueue will go in with no exceptions, but a second enqueue will throw an exception. Even after setting the buffer size to 1, if the server is shut down, an enqueue will fail. When the server comes back up, an enqueue will go without throwing an exception, however the tuple will not make it to the server.
 
What is the best way to implement reconnect logic?

Issue/Introduction

Enqueue client, when to detect when connection is lost for reconnection?

Resolution

Please see the Reconnecting Client example described here:
  StreamBase Documentation > Samples Guide > Client Sample

A further explanation is this:
The StreamBase Client wire-protocol does not guarantee message delivery, so in the absence of a network exception or shutdown message from the server, the client will optimistically send tuples to the open socket or wait to dequeue.

Case 1: "if the server is shutdown and I try to enqueue, the first enqueue will go in with no exceptions, but a second enqueue will throw an exception."
The exception is caused by the first enqueue attempt, which then changes the client state such that the second attempt fails.

Case 2: "when I bring the server back up, an enqueue will go without throwing an exception, however the tuple will not make it to the server."
This is possibly cause by a race condition. Note that the ReconnectingEnqueuer waits for both the Server be "Listening" and for the "default" container to also initialize:

Java code sample
// ...we have to wait both the server and the application to be available.
String [] containers=null;
try {
  containers = client.listEntities(EntityType.CONTAINER);
} catch (StreamBaseException e) {
  try {
    client.close();
  } catch (StreamBaseException e1) {
  }
  client=null;
}
for (String container : containers) {
  if ("default".equals(container)) {
    System.out.println(PREFIX + "Connected to StreamBase at " + uri);
    return client;
  }
}

If you try to enqueue as soon as "client = new StreamBaseClient(uri)" succeeds, the target container/stream may not be ready to dequeue tuples. Once "containers = client.listEntities(EntityType.CONTAINER)" contains the desired container, then the next enqueue should succeed in being received by the application.
If you need to ensure every tuple is accounted for, place a sequence number field in the tuple and raise an alert in the recipient (either client or server application) when a sequence number is skipped. You can either have the sender cache tuples and the recipient request any missing (like the FIX protocol) or you can have the recipient send an acknowledgment for every one received (like TCP) or have the recipient send a bulk acknowledgment every few seconds (like Kafka).