@ekoby I tried your Socket pattern and it works nicely, except I found a bug in AsynchSocketImpl
, probably caused by a problem in InputChannel
What is the proper way to report OpenZiti bugs?
Here's my code
public static void hitZitiService(@Nonnull ZitiContext zitiContext, @Nonnull String serviceName) throws Exception {
try (Socket socket = zitiContext.connect(serviceName, 8111)) {
socket.setSoTimeout(1000);
InputStream zitiInputStream = socket.getInputStream();
try {
byte[] buff = new byte[1024];
while (true){
try {
int rxLength = zitiInputStream.read(buff, 0, buff.length);
if (rxLength < 0) {
logger.info("=== [Received message length = "+rxLength+"]");
} else {
// Log the message
String message = new String(buff, 0, rxLength, StandardCharsets.UTF_8);
logger.info("=== " + StringUtils.toPrintable(message, 200));
}
} catch (SocketTimeoutException e) {
logger.debug("Socket timeout, trying again", e);
}
}
} catch (Exception e) {
throw new Exception("Failed to receive message", e);
}
}
}
The service sends a welcome message, which is read successfully by the first call to read()
.
The second call to read()
throws a SocketTimeoutException, which is expected as there are no more messages from the service
Then the third call to read()
is blocked forever, it should timeout.
It seems one of the mutex locks is not being released when the timeout exception is thrown.
Debugging shows that the second call to read()
leaves AsynchSocketImpl:159
rf
as [Not completed]
.
val rf = CompletableFuture<Int>()
val to = (getOption(SocketOptions.SO_TIMEOUT) as Number).toLong()
channel.read(input, 0, TimeUnit.MILLISECONDS, rf,
object : CompletionHandler<Int, CompletableFuture<Int>> {
Can't quite get my head around the code, but I think the cause is InputChannel:122
which only completes the handler if data is copied, and timeout exceptions don't copy any data.
if (copied > 0) {
inputSupport.mut.unlock()
handler.completed(copied, att)
return
}
FYI - I regularly use socket timeouts to allow applications to shutdown in an orderly manner rather than hang waiting for input they are never going to receive.
Please can you let me know where I should submit this bug report.
FYI - there's another bug I haven't pinned down yet that is not Java specific. My Ziti terminators sometimes disappear leaving the services unusable. Restarting the Ziti tunneller recreates the terminators, but I won't be able to do this for endpoints deployed to hosts where I have no external access. When I work out how to reproduce this reliably, I'll report it.