use of org.apache.flink.runtime.io.network.NetworkClientHandler in project flink by apache.
the class PartitionRequestClientFactory method connect.
private NettyPartitionRequestClient connect(ConnectionID connectionId) throws RemoteTransportException, InterruptedException {
try {
// It's important to use `sync` here because it waits for this future until it is
// done, and rethrows the cause of the failure if this future failed. `await` only
// waits for this future to be completed, without throwing the error.
Channel channel = nettyClient.connect(connectionId.getAddress()).sync().channel();
NetworkClientHandler clientHandler = channel.pipeline().get(NetworkClientHandler.class);
return new NettyPartitionRequestClient(channel, clientHandler, connectionId, this);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
throw new RemoteTransportException("Connecting to remote task manager '" + connectionId.getAddress() + "' has failed. This might indicate that the remote task " + "manager has been lost.", connectionId.getAddress(), e);
}
}
use of org.apache.flink.runtime.io.network.NetworkClientHandler 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();
NetworkClientHandler 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.NetworkClientHandler in project flink by apache.
the class ClientTransportErrorHandlingTest method testExceptionOnWrite.
/**
* Verifies that failed client requests via {@link PartitionRequestClient} are correctly
* attributed to the respective {@link RemoteInputChannel}.
*/
@Test
public void testExceptionOnWrite() throws Exception {
NettyProtocol protocol = new NettyProtocol(mock(ResultPartitionProvider.class), mock(TaskEventDispatcher.class)) {
@Override
public ChannelHandler[] getServerChannelHandlers() {
return new ChannelHandler[0];
}
};
// We need a real server and client in this test, because Netty's EmbeddedChannel is
// not failing the ChannelPromise of failed writes.
NettyServerAndClient serverAndClient = initServerAndClient(protocol, createConfig());
Channel ch = connect(serverAndClient);
NetworkClientHandler handler = getClientHandler(ch);
// Last outbound handler throws Exception after 1st write
ch.pipeline().addFirst(new ChannelOutboundHandlerAdapter() {
int writeNum = 0;
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (writeNum >= 1) {
throw new RuntimeException("Expected test exception.");
}
writeNum++;
ctx.write(msg, promise);
}
});
PartitionRequestClient requestClient = new NettyPartitionRequestClient(ch, handler, mock(ConnectionID.class), mock(PartitionRequestClientFactory.class));
// Create input channels
RemoteInputChannel[] rich = new RemoteInputChannel[] { createRemoteInputChannel(), createRemoteInputChannel() };
final CountDownLatch sync = new CountDownLatch(1);
// Do this with explicit synchronization. Otherwise this is not robust against slow timings
// of the callback (e.g. we cannot just verify that it was called once, because there is
// a chance that we do this too early).
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
sync.countDown();
return null;
}
}).when(rich[1]).onError(isA(LocalTransportException.class));
// First request is successful
requestClient.requestSubpartition(new ResultPartitionID(), 0, rich[0], 0);
// Second request is *not* successful
requestClient.requestSubpartition(new ResultPartitionID(), 0, rich[1], 0);
// Wait for the notification and it could confirm all the request operations are done
if (!sync.await(TestingUtils.TESTING_DURATION.toMillis(), TimeUnit.MILLISECONDS)) {
fail("Timed out after waiting for " + TestingUtils.TESTING_DURATION.toMillis() + " ms to be notified about the channel error.");
}
// Only the second channel should be notified about the error
verify(rich[0], times(0)).onError(any(LocalTransportException.class));
shutdown(serverAndClient);
}
use of org.apache.flink.runtime.io.network.NetworkClientHandler in project flink by apache.
the class ClientTransportErrorHandlingTest method testChannelClosedOnExceptionDuringErrorNotification.
/**
* Verifies that the channel is closed if there is an error *during* error notification.
*/
@Test
public void testChannelClosedOnExceptionDuringErrorNotification() throws Exception {
EmbeddedChannel ch = createEmbeddedChannel();
NetworkClientHandler handler = getClientHandler(ch);
RemoteInputChannel rich = addInputChannel(handler);
doThrow(new RuntimeException("Expected test exception")).when(rich).onError(any(Throwable.class));
ch.pipeline().fireExceptionCaught(new Exception());
assertFalse(ch.isActive());
}
use of org.apache.flink.runtime.io.network.NetworkClientHandler in project flink by apache.
the class ClientTransportErrorHandlingTest method testConnectionResetByPeer.
/**
* Verifies that "Connection reset by peer" Exceptions are special-cased and are reported as an
* instance of {@link RemoteTransportException}.
*/
@Test
public void testConnectionResetByPeer() throws Throwable {
EmbeddedChannel ch = createEmbeddedChannel();
NetworkClientHandler handler = getClientHandler(ch);
RemoteInputChannel rich = addInputChannel(handler);
final Throwable[] error = new Throwable[1];
// Verify the Exception
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Throwable cause = (Throwable) invocation.getArguments()[0];
try {
assertEquals(RemoteTransportException.class, cause.getClass());
assertNotEquals("Connection reset by peer", cause.getMessage());
assertEquals(IOException.class, cause.getCause().getClass());
assertEquals("Connection reset by peer", cause.getCause().getMessage());
} catch (Throwable t) {
error[0] = t;
}
return null;
}
}).when(rich).onError(any(Throwable.class));
ch.pipeline().fireExceptionCaught(new IOException("Connection reset by peer"));
assertNull(error[0]);
}
Aggregations