Skip to content

Commit

Permalink
Fix test failure and improve debuggability
Browse files Browse the repository at this point in the history
  • Loading branch information
normanmaurer committed Mar 6, 2020
1 parent 75e2443 commit 05fce96
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,17 @@ public final void channelActive(ChannelHandlerContext ctx) {
@Override
public final void channelInactive(ChannelHandlerContext ctx) {
if (hasSubscriber()) {
tryFailSubscriber(new StacklessClosedChannelException());
tryFailSubscriber(StacklessClosedChannelException.newInstance(
H2ParentConnectionContext.class, "channelInactive(...)"));
}
doConnectionCleanup();
}

@Override
public final void handlerRemoved(ChannelHandlerContext ctx) {
if (hasSubscriber()) {
tryFailSubscriber(new StacklessClosedChannelException());
tryFailSubscriber(StacklessClosedChannelException.newInstance(
H2ParentConnectionContext.class, "handlerRemoved(...)"));
}
doConnectionCleanup();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.servicetalk.concurrent.api.internal.SpScPublisherProcessor;
import io.servicetalk.concurrent.internal.SequentialCancellable;

import io.servicetalk.concurrent.internal.ThrowableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -249,7 +250,8 @@ private Single<C> selectConnection0(Predicate<C> selector) {
final List<Host<ResolvedAddress, C>> activeHosts = this.activeHosts;
if (activeHosts.isEmpty()) {
// This is the case when SD has emitted some items but none of the hosts are active.
return failed(new StacklessNoAvailableHostException("No hosts are available to connect."));
return failed(StacklessNoAvailableHostException.newInstance(
"No hosts are available to connect.", RoundRobinLoadBalancer.class, "selectConnection0(...)"));
}

final int cursor = (indexUpdater.getAndIncrement(this) & Integer.MAX_VALUE) % activeHosts.size();
Expand Down Expand Up @@ -428,13 +430,17 @@ private static final class MutableAddressHost<Addr, C extends ListenableAsyncClo
}

private static final class StacklessNoAvailableHostException extends NoAvailableHostException {
StacklessNoAvailableHostException(final String message) {
private StacklessNoAvailableHostException(final String message) {
super(message);
}

@Override
public Throwable fillInStackTrace() {
return this;
}

public static StacklessNoAvailableHostException newInstance(String message, Class<?> clazz, String method) {
return ThrowableUtils.unknownStackTrace(new StacklessNoAvailableHostException(message), clazz, method);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ private boolean failIfWriteActive(ChannelOutboundListener newChannelOutboundList
// never notify the write writeSubscriber of the inactive event. So if the channel is inactive we notify
// the writeSubscriber.
if (!channel().isActive()) {
newChannelOutboundListener.channelClosed(new StacklessClosedChannelException());
newChannelOutboundListener.channelClosed(
StacklessClosedChannelException.newInstance(DefaultNettyConnection.class, "failIfWriteActive(..)"));
return false;
}
return true;
Expand Down Expand Up @@ -555,7 +556,8 @@ public void handlerAdded(ChannelHandlerContext ctx) {
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
if (subscriber != null) {
tryFailSubscriber(new StacklessClosedChannelException());
tryFailSubscriber(StacklessClosedChannelException.newInstance(
DefaultNettyConnection.class, "handlerRemoved(...)"));
}
}

Expand All @@ -582,7 +584,8 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
connection.channelOutboundListener.channelOutboundClosed();
} else if (evt == ChannelOutputShutdownEvent.INSTANCE) {
connection.closeHandler.channelClosedOutbound(ctx);
connection.channelOutboundListener.channelClosed(new StacklessClosedChannelException());
connection.channelOutboundListener.channelClosed(StacklessClosedChannelException.newInstance(
DefaultNettyConnection.class, "userEventTriggered(...)"));
} else if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
// Notify close handler first to enhance error reporting
connection.closeHandler.channelClosedInbound(ctx);
Expand Down Expand Up @@ -616,7 +619,8 @@ public void channelActive(ChannelHandlerContext ctx) {

@Override
public void channelInactive(ChannelHandlerContext ctx) {
Throwable closedChannelException = new StacklessClosedChannelException();
Throwable closedChannelException = StacklessClosedChannelException.newInstance(
DefaultNettyConnection.class, "channelInactive(...)");
tryFailSubscriber(closedChannelException);
connection.channelOutboundListener.channelClosed(closedChannelException);
connection.nettyChannelPublisher.channelInboundClosed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void exceptionCaught(Throwable throwable) {

void channelInboundClosed() {
assertInEventloop();
Throwable error = new StacklessClosedChannelException();
Throwable error = StacklessClosedChannelException.newInstance(NettyChannelPublisher.class, "channelInboundClosed");
fatalError = error;
exceptionCaught(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@
*/
package io.servicetalk.transport.netty.internal;

import io.servicetalk.concurrent.internal.ThrowableUtils;

import java.nio.channels.ClosedChannelException;

public final class StacklessClosedChannelException extends ClosedChannelException {

private StacklessClosedChannelException() { }

@Override
public Throwable fillInStackTrace() {
// Don't fill in the stacktrace to reduce performance overhead
return this;
}

public static StacklessClosedChannelException newInstance(Class<?> clazz, String method) {
return ThrowableUtils.unknownStackTrace(new StacklessClosedChannelException(), clazz, method);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ public void testNoErrorEnrichmentWithoutCloseHandlerOnError() {
writeListener.verifyFailure(exCaptor);

// Exception should NOT be of type CloseEventObservedException
assertThat(exCaptor.getValue(), instanceOf(ClosedChannelException.class));
assertThat(exCaptor.getValue(), instanceOf(StacklessClosedChannelException.class));
assertThat(exCaptor.getValue().getCause(), nullValue());
assertThat(exCaptor.getValue().getStackTrace()[0].getClassName(),
equalTo(DefaultNettyConnection.class.getName()));
Expand Down

0 comments on commit 05fce96

Please sign in to comment.