use of org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException in project flink by apache.
the class ClientTransportErrorHandlingTest method testWrappingOfRemoteErrorMessage.
/**
* Verifies that {@link NettyMessage.ErrorResponse} messages are correctly wrapped in
* {@link RemoteTransportException} instances.
*/
@Test
public void testWrappingOfRemoteErrorMessage() throws Exception {
EmbeddedChannel ch = createEmbeddedChannel();
PartitionRequestClientHandler handler = getClientHandler(ch);
// Create input channels
RemoteInputChannel[] rich = new RemoteInputChannel[] { createRemoteInputChannel(), createRemoteInputChannel() };
for (RemoteInputChannel r : rich) {
when(r.getInputChannelId()).thenReturn(new InputChannelID());
handler.addInputChannel(r);
}
// Error msg for channel[0]
ch.pipeline().fireChannelRead(new NettyMessage.ErrorResponse(new RuntimeException("Expected test exception"), rich[0].getInputChannelId()));
try {
// Exception should not reach end of pipeline...
ch.checkException();
} catch (Exception e) {
fail("The exception reached the end of the pipeline and " + "was not handled correctly by the last handler.");
}
verify(rich[0], times(1)).onError(isA(RemoteTransportException.class));
verify(rich[1], never()).onError(any(Throwable.class));
// Fatal error for all channels
ch.pipeline().fireChannelRead(new NettyMessage.ErrorResponse(new RuntimeException("Expected test exception")));
try {
// Exception should not reach end of pipeline...
ch.checkException();
} catch (Exception e) {
fail("The exception reached the end of the pipeline and " + "was not handled correctly by the last handler.");
}
verify(rich[0], times(2)).onError(isA(RemoteTransportException.class));
verify(rich[1], times(1)).onError(isA(RemoteTransportException.class));
}
use of org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException in project flink by apache.
the class PartitionRequestClientHandler method decodeMsg.
private boolean decodeMsg(Object msg, boolean isStagedBuffer) throws Throwable {
final Class<?> msgClazz = msg.getClass();
// ---- Buffer --------------------------------------------------------
if (msgClazz == NettyMessage.BufferResponse.class) {
NettyMessage.BufferResponse bufferOrEvent = (NettyMessage.BufferResponse) msg;
RemoteInputChannel inputChannel = inputChannels.get(bufferOrEvent.receiverId);
if (inputChannel == null) {
bufferOrEvent.releaseBuffer();
cancelRequestFor(bufferOrEvent.receiverId);
return true;
}
return decodeBufferOrEvent(inputChannel, bufferOrEvent, isStagedBuffer);
} else // ---- Error ---------------------------------------------------------
if (msgClazz == NettyMessage.ErrorResponse.class) {
NettyMessage.ErrorResponse error = (NettyMessage.ErrorResponse) msg;
SocketAddress remoteAddr = ctx.channel().remoteAddress();
if (error.isFatalError()) {
notifyAllChannelsOfErrorAndClose(new RemoteTransportException("Fatal error at remote task manager '" + remoteAddr + "'.", remoteAddr, error.cause));
} else {
RemoteInputChannel inputChannel = inputChannels.get(error.receiverId);
if (inputChannel != null) {
if (error.cause.getClass() == PartitionNotFoundException.class) {
inputChannel.onFailedPartitionRequest();
} else {
inputChannel.onError(new RemoteTransportException("Error at remote task manager '" + remoteAddr + "'.", remoteAddr, error.cause));
}
}
}
} else {
throw new IllegalStateException("Received unknown message from producer: " + msg.getClass());
}
return true;
}
use of org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException in project flink by apache.
the class PartitionRequestClientHandler method exceptionCaught.
/**
* Called on exceptions in the client handler pipeline.
*
* <p> Remote exceptions are received as regular payload.
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof TransportException) {
notifyAllChannelsOfErrorAndClose(cause);
} else {
final SocketAddress remoteAddr = ctx.channel().remoteAddress();
final TransportException tex;
// Improve on the connection reset by peer error message
if (cause instanceof IOException && cause.getMessage().equals("Connection reset by peer")) {
tex = new RemoteTransportException("Lost connection to task manager '" + remoteAddr + "'. This indicates " + "that the remote task manager was lost.", remoteAddr, cause);
} else {
tex = new LocalTransportException(cause.getMessage(), ctx.channel().localAddress(), cause);
}
notifyAllChannelsOfErrorAndClose(tex);
}
}
use of org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException in project flink by apache.
the class PartitionRequestClientHandler method channelInactive.
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// channels have been removed. This indicates a problem with the remote task manager.
if (!inputChannels.isEmpty()) {
final SocketAddress remoteAddr = ctx.channel().remoteAddress();
notifyAllChannelsOfErrorAndClose(new RemoteTransportException("Connection unexpectedly closed by remote task manager '" + remoteAddr + "'. " + "This might indicate that the remote task manager was lost.", remoteAddr));
}
super.channelInactive(ctx);
}
use of org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException in project flink by apache.
the class ClientTransportErrorHandlingTest method testExceptionOnRemoteClose.
/**
* Verifies that unexpected remote closes are reported as an instance of
* {@link RemoteTransportException}.
*/
@Test
public void testExceptionOnRemoteClose() throws Exception {
NettyProtocol protocol = new NettyProtocol() {
@Override
public ChannelHandler[] getServerChannelHandlers() {
return new ChannelHandler[] { // Close on read
new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().close();
}
} };
}
@Override
public ChannelHandler[] getClientChannelHandlers() {
return new PartitionRequestProtocol(mock(ResultPartitionProvider.class), mock(TaskEventDispatcher.class), mock(NetworkBufferPool.class)).getClientChannelHandlers();
}
};
NettyServerAndClient serverAndClient = initServerAndClient(protocol, createConfig());
Channel ch = connect(serverAndClient);
PartitionRequestClientHandler handler = getClientHandler(ch);
// Create input channels
RemoteInputChannel[] rich = new RemoteInputChannel[] { createRemoteInputChannel(), createRemoteInputChannel() };
final CountDownLatch sync = new CountDownLatch(rich.length);
Answer<Void> countDownLatch = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
sync.countDown();
return null;
}
};
for (RemoteInputChannel r : rich) {
doAnswer(countDownLatch).when(r).onError(any(Throwable.class));
handler.addInputChannel(r);
}
// Write something to trigger close by server
ch.writeAndFlush(Unpooled.buffer().writerIndex(16));
// Wait for the notification
if (!sync.await(TestingUtils.TESTING_DURATION().toMillis(), TimeUnit.MILLISECONDS)) {
fail("Timed out after waiting for " + TestingUtils.TESTING_DURATION().toMillis() + " ms to be notified about remote connection close.");
}
// All the registered channels should be notified.
for (RemoteInputChannel r : rich) {
verify(r).onError(isA(RemoteTransportException.class));
}
shutdown(serverAndClient);
}
Aggregations