use of alluxio.network.protocol.RPCBlockReadResponse in project alluxio by Alluxio.
the class ClientHandlerTest method channelRead0ResponseReceived.
/**
* Makes sure that the response is received as expected.
*/
@Test
public void channelRead0ResponseReceived() throws IOException {
final ClientHandler.ResponseListener listener = Mockito.mock(ClientHandler.ResponseListener.class);
final DataBuffer buffer = Mockito.mock(DataBuffer.class);
final RPCResponse response = new RPCBlockReadResponse(0, 0, 0, buffer, RPCResponse.Status.SUCCESS);
mHandler.addListener(listener);
mHandler.channelRead0(mContext, response);
Mockito.verify(listener).onResponseReceived(response);
}
use of alluxio.network.protocol.RPCBlockReadResponse in project alluxio by Alluxio.
the class NettyUnderFileSystemBlockReader method read.
@Override
public ByteBuffer read(InetSocketAddress address, long blockId, long offset, long length, long sessionId, boolean noCache) throws IOException {
Channel channel = null;
ClientHandler clientHandler = null;
Metrics.NETTY_UFS_BLOCK_READ_OPS.inc();
try {
channel = mContext.acquireNettyChannel(address);
if (!(channel.pipeline().last() instanceof ClientHandler)) {
channel.pipeline().addLast(new ClientHandler());
}
clientHandler = (ClientHandler) channel.pipeline().last();
SingleResponseListener listener = new SingleResponseListener();
clientHandler.addListener(listener);
ChannelFuture channelFuture = channel.writeAndFlush(new RPCUnderFileSystemBlockReadRequest(blockId, offset, length, sessionId, noCache));
channelFuture = channelFuture.sync();
if (channelFuture.isDone() && !channelFuture.isSuccess()) {
LOG.error("Failed to read from %s for block %d with error %s.", address.toString(), blockId, channelFuture.cause());
throw new IOException(channelFuture.cause());
}
RPCResponse response = listener.get(NettyClient.TIMEOUT_MS, TimeUnit.MILLISECONDS);
switch(response.getType()) {
case RPC_BLOCK_READ_RESPONSE:
RPCBlockReadResponse blockResponse = (RPCBlockReadResponse) response;
LOG.debug("Data {} from machine {} received", blockId, address);
RPCResponse.Status status = blockResponse.getStatus();
if (status == RPCResponse.Status.SUCCESS) {
// always clear the previous response before reading another one
close();
mReadResponse = blockResponse;
return blockResponse.getPayloadDataBuffer().getReadOnlyByteBuffer();
}
throw new IOException(status.getMessage() + " response: " + blockResponse);
case RPC_ERROR_RESPONSE:
RPCErrorResponse error = (RPCErrorResponse) response;
throw new IOException(error.getStatus().getMessage());
default:
throw new IOException(ExceptionMessage.UNEXPECTED_RPC_RESPONSE.getMessage(response.getType(), RPCMessage.Type.RPC_BLOCK_READ_RESPONSE));
}
} catch (Exception e) {
Metrics.NETTY_UFS_BLOCK_READ_FAILURES.inc();
try {
if (channel != null) {
channel.close().sync();
}
} catch (InterruptedException ee) {
throw new RuntimeException(ee);
}
throw new IOException(e);
} finally {
if (clientHandler != null) {
clientHandler.removeListeners();
}
if (channel != null) {
mContext.releaseNettyChannel(address, channel);
}
}
}
use of alluxio.network.protocol.RPCBlockReadResponse in project alluxio by Alluxio.
the class BlockDataServerHandler method handleUnderFileSystemBlockReadRequest.
/**
* Handles a {@link RPCUnderFileSystemBlockReadRequest} by reading the data through a
* {@link BlockReader} provided by the block worker. This method assumes the data is available
* in the UFS returns an error status if the data is not available.
*
* @param ctx The context of this request which handles the result of this operation
* @param req The initiating {@link RPCBlockReadRequest}
* @throws IOException if an I/O error occurs when reading the data requested
*/
public void handleUnderFileSystemBlockReadRequest(final ChannelHandlerContext ctx, final RPCUnderFileSystemBlockReadRequest req) throws IOException {
final long blockId = req.getBlockId();
final long offset = req.getOffset();
final long len = req.getLength();
final long sessionId = req.getSessionId();
final boolean noCache = req.getNoCache();
try {
DataBuffer buffer = null;
req.validate();
BlockReader reader = mWorker.readUfsBlock(sessionId, blockId, offset, noCache);
ByteBuffer data = reader.read(offset, len);
if (data != null && data.remaining() > 0) {
buffer = new DataByteBuffer(data, data.remaining());
Metrics.BYTES_READ_UFS.inc(buffer.getLength());
}
RPCBlockReadResponse resp = new RPCBlockReadResponse(blockId, offset, data.remaining(), buffer, RPCResponse.Status.SUCCESS);
ChannelFuture future = ctx.writeAndFlush(resp);
if (buffer != null) {
future.addListener(new ReleasableResourceChannelListener(buffer));
}
LOG.debug("Preparation for responding to remote block request for: {} done.", blockId);
} catch (Exception e) {
LOG.error("Exception reading block {}", blockId, e);
RPCBlockReadResponse resp;
if (e instanceof BlockDoesNotExistException) {
resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE);
} else {
resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.UFS_READ_FAILED);
}
ChannelFuture future = ctx.writeAndFlush(resp);
future.addListener(ChannelFutureListener.CLOSE);
}
}
use of alluxio.network.protocol.RPCBlockReadResponse in project alluxio by Alluxio.
the class BlockDataServerHandler method handleBlockReadRequest.
/**
* Handles a {@link RPCBlockReadRequest} by reading the data through a {@link BlockReader}
* provided by the block worker. This method assumes the data is available in the local storage
* of the worker and returns an error status if the data is not available.
*
* @param ctx The context of this request which handles the result of this operation
* @param req The initiating {@link RPCBlockReadRequest}
* @throws IOException if an I/O error occurs when reading the data requested
*/
void handleBlockReadRequest(final ChannelHandlerContext ctx, final RPCBlockReadRequest req) throws IOException {
final long blockId = req.getBlockId();
final long offset = req.getOffset();
final long len = req.getLength();
final long lockId = req.getLockId();
final long sessionId = req.getSessionId();
BlockReader reader = null;
DataBuffer buffer;
try {
req.validate();
reader = mWorker.readBlockRemote(sessionId, blockId, lockId);
final long fileLength = reader.getLength();
validateBounds(req, fileLength);
final long readLength = returnLength(offset, len, fileLength);
buffer = getDataBuffer(req, reader, readLength);
Metrics.BYTES_READ_REMOTE.inc(buffer.getLength());
RPCBlockReadResponse resp = new RPCBlockReadResponse(blockId, offset, readLength, buffer, RPCResponse.Status.SUCCESS);
ChannelFuture future = ctx.writeAndFlush(resp);
future.addListener(new ClosableResourceChannelListener(reader));
future.addListener(new ReleasableResourceChannelListener(buffer));
mWorker.accessBlock(sessionId, blockId);
LOG.debug("Preparation for responding to remote block request for: {} done.", blockId);
} catch (Exception e) {
LOG.error("Exception reading block {}", blockId, e);
RPCBlockReadResponse resp;
if (e instanceof BlockDoesNotExistException) {
resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE);
} else {
resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.UFS_READ_FAILED);
}
ChannelFuture future = ctx.writeAndFlush(resp);
future.addListener(ChannelFutureListener.CLOSE);
if (reader != null) {
reader.close();
}
}
}
use of alluxio.network.protocol.RPCBlockReadResponse in project alluxio by Alluxio.
the class NettyRemoteBlockReader method readRemoteBlock.
@Override
public ByteBuffer readRemoteBlock(InetSocketAddress address, long blockId, long offset, long length, long lockId, long sessionId) throws IOException {
Channel channel = null;
ClientHandler clientHandler = null;
Metrics.NETTY_BLOCK_READ_OPS.inc();
try {
channel = mContext.acquireNettyChannel(address);
if (!(channel.pipeline().last() instanceof ClientHandler)) {
channel.pipeline().addLast(new ClientHandler());
}
clientHandler = (ClientHandler) channel.pipeline().last();
SingleResponseListener listener = new SingleResponseListener();
clientHandler.addListener(listener);
ChannelFuture channelFuture = channel.writeAndFlush(new RPCBlockReadRequest(blockId, offset, length, lockId, sessionId));
channelFuture = channelFuture.sync();
if (channelFuture.isDone() && !channelFuture.isSuccess()) {
LOG.error("Failed to write to %s for block %d with error %s.", address.toString(), blockId, channelFuture.cause());
throw new IOException(channelFuture.cause());
}
RPCResponse response = listener.get(NettyClient.TIMEOUT_MS, TimeUnit.MILLISECONDS);
switch(response.getType()) {
case RPC_BLOCK_READ_RESPONSE:
RPCBlockReadResponse blockResponse = (RPCBlockReadResponse) response;
LOG.debug("Data {} from remote machine {} received", blockId, address);
RPCResponse.Status status = blockResponse.getStatus();
if (status == RPCResponse.Status.SUCCESS) {
// always clear the previous response before reading another one
close();
mReadResponse = blockResponse;
return blockResponse.getPayloadDataBuffer().getReadOnlyByteBuffer();
}
throw new IOException(status.getMessage() + " response: " + blockResponse);
case RPC_ERROR_RESPONSE:
RPCErrorResponse error = (RPCErrorResponse) response;
throw new IOException(error.getStatus().getMessage());
default:
throw new IOException(ExceptionMessage.UNEXPECTED_RPC_RESPONSE.getMessage(response.getType(), RPCMessage.Type.RPC_BLOCK_READ_RESPONSE));
}
} catch (Exception e) {
Metrics.NETTY_BLOCK_READ_FAILURES.inc();
try {
if (channel != null) {
channel.close().sync();
}
} catch (InterruptedException ee) {
throw Throwables.propagate(ee);
}
throw new IOException(e);
} finally {
if (clientHandler != null) {
clientHandler.removeListeners();
}
if (channel != null) {
mContext.releaseNettyChannel(address, channel);
}
}
}
Aggregations