0

I'm facing with strange problem.

My application (works with Payara 4.1.1.163) uses Websockets to send messages between clients. TyrusRemoteEndpoint is used for this functionality.

After deployment it works well around 3-4 days, and then (if application were not deployed or redeployed this time) tyrus suddenly blocks thread (or even threads) when calling a function:

session.getBasicRemote().sendObject(obj);

Using VisualVM I've dumped all threads and see the following:

"http-thread-pool(56)" - Thread t@209
   java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <6929ab6a> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
    at org.glassfish.tyrus.core.TyrusFuture.get(TyrusFuture.java:77)
    at org.glassfish.tyrus.core.TyrusRemoteEndpoint$Basic.sendObject(TyrusRemoteEndpoint.java:183)

It seems that this thread holds in a forever wait. Messages do not send for this client.

If I use syncronized blocks it even causes deadlock and all http-thread-pools (that concerns websockets) became blocked.

What can cause such an issue? How can I cope with it? Should I need to provide something else? Thank you in advance!

P.S. I'm using default Payara settings concerning thread pools (if it can help).

Luxor
  • 351
  • 1
  • 3
  • 17

1 Answers1

0

Seems that this is a bug in tyrus-websocket library.

It can be at least resolved by recovering application using

getAsyncRemote()

instead of

getBasicRemote()

in the following way:

Future<Void> f = session.getAsyncRemote().sendObject(...)        
try {
    f.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
    throw new IOException(e);
} catch (ExecutionException e) {
    Throwable cause = e.getCause();
    if (cause instanceof IOException) {
        throw (IOException) cause;
    } else if (cause instanceof EncodeException) {
        throw (EncodeException) cause;
    } else {
        throw new IOException(e);
    }
} catch (TimeoutException e) {
    throw new IOException(e);
}

In this case we are using timeout and at least ensure that our application can be recovered after that issue.

I've also checked this repository for the newest version of tyrus and cannot say that they've fixed an issue. Probably it should be posted as a bug of Payara or Glassfish.

Luxor
  • 351
  • 1
  • 3
  • 17