jhalterman / lyra

High availability RabbitMQ client
Apache License 2.0
262 stars 74 forks source link

Lyra throws `AlreadyClosedException` calling `isOpen` on a closed channel #58

Open jaguililla opened 8 years ago

jaguililla commented 8 years ago

Lyra throws AlreadyClosedException calling isOpen on a closed channel

DimaGolomozy commented 7 years ago

What if RetryableResource#handleCommonMethods will return Object and not void, and add the common method "isOpen" with a return value

Object handleCommonMethods(Object delegate, Method method, Object[] args) throws Throwable {
    if ("abort".equals(method.getName()) || "close".equals(method.getName())) {
      try {
        Reflection.invoke(delegate, method, args);
        return true;
      } finally {
        closed = true;
        afterClosure();
        interruptWaiters();
      }
    } else if ("isOpen".equals(method.getName()))
      return Reflection.invoke(delegate, method, args);
    else if ("addShutdownListener".equals(method.getName()) && args[0] != null)
      shutdownListeners.add((ShutdownListener) args[0]);
    else if ("removeShutdownListener".equals(method.getName()) && args[0] != null)
      shutdownListeners.remove((ShutdownListener) args[0]);
    return null;
  }

and in the ChannelHandler#invoke method:

@Override
  public Object invoke(Object ignored, final Method method, final Object[] args) throws Throwable {
    Object result = handleCommonMethods(delegate, method, args);
    if (result != null)
        return result;
    if (closed && method.getDeclaringClass().isAssignableFrom(Channel.class))
      throw new AlreadyClosedException(delegate.getCloseReason());
.......

It seems to work, and handles the isOpen() afterclose(). Also, handles calling close() after a close() throws en exception. But, I cant change the ChannelHandlerTest#shouldThrowOnAlreadyClosedChannelInvocation to throw the exception.

any ideas?