Reputation: 21309
I have a long running Tibrv connection from a Java process.
I was surprised to see this log entry today (printed on stderr):
2018-02-01 08:15:44 RV: TIB/Rendezvous Error Not Handled by Process: {ADV_CLASS="WARN" ADV_SOURCE="SYSTEM" ADV_NAME="RVD.DISCONNECTED"}
What is the right way to catch this error and reconnect?
My process needs to be fault tolerant. (I think the server on the other side was rebooted.)
Sample connection code:
Tibrv.open(Tibrv.IMPL_NATIVE);
final TibrvRvdTransport tibrvRvdTransport =
new TibrvRvdTransport(tibrvService, nullableTibrvNetwork, tibrvDaemon);
According to the official Tibrv docs (p282), there is a System Advisory Message called _RV.WARN.SYSTEM.RVD.DISCONNECTED
. However, I don't know the correct way to listen for this message, nor attempt recovery upon receipt.
Upvotes: 0
Views: 1303
Reputation: 21309
This took me a while to figure out, so I am answering my own question.
In short, the Tibrv Java library uses a private thread to automatically monitor for disconnect and re-connect. The purpose of 'user-space' monitoring is to provide gracefully handling of these events (fault tolerance, etc.).
The technical solution is to listen for two special RVD messages:
_RV.WARN.SYSTEM.RVD.DISCONNECTED
_RV.INFO.SYSTEM.RVD.CONNECTED
A single TibrvListener
with subject wildcard can be used.
final String subjectWildcard = "_RV.*.SYSTEM.RVD.*";
final Object nullableClosure = null;
new TibrvListener(
Tibrv.defaultQueue(),
// @NotThreadSafe
new TibrvMsgCallback() {
@Override
public void onMsg(TibrvListener tibrvListener, TibrvMsg tibrvMsg) {
final String sendSubject = tibrvMsg.getSendSubject();
if ("_RV.WARN.SYSTEM.RVD.DISCONNECTED".equals(sendSubject)) {
// TODO
}
else if ("_RV.INFO.SYSTEM.RVD.CONNECTED".equals(sendSubject)) {
// TODO
}
}
},
tibrvRvdTransport, subjectWildcard, nullableClosure);
// Next: Setup a daemon thread to dispatch incoming Tibrv messages.
{
final Thread thread = new Thread(() -> {
final TibrvQueue tibrvQueue = Tibrv.defaultQueue();
while (true) {
try {
tibrvQueue.dispatch();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.setDaemon(true);
thread.start();
}
Credit for TibrvListener
and TibrvQueue.dispatch()
How to test disconnect and re-connect events:
$ tibrvlisten -service 8800 -daemon tcp:8800 TEST.MESSAGE
$ tibrvsend -service 8800 -daemon ${tibrvlisten.hostname}:8800 TEST.MESSAGE hello
tibrvlisten
should log: subject=TEST.MESSAGE, message={DATA="hello"}
new TibrvRvdTransport("8800", null, "${tibrvlisten.hostname}:8800")
tibrvlisten
with Ctrl+C, then kill background process rvd
, e.g., $ ps -efjww | egrep 'rvd +-listen' | awk '{print $2}' | xargs kill
final TibrvMsg m = new TibrvMsg();
m.setSendSubject("TEST.MESSAGE");
m.add("DATA", "hello");
tibrvRvdTransport.send(m);
send()
will fail with TibrvException
:
error=21, message="Could not connect to daemon"int TibrvException.error
values can be found here:
TibrvStatus
, e.g., DAEMON_NOT_CONNECTED = 21
tibrvlisten
and wait for Java background thread to automatically re-connect.Upvotes: 1