use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class InMemoryCloudDestinationErrorSimulationTest method testGetBlobInfoErrorSimulation.
/**
* test error simulation for GetBlobInfoRequest
* @throws Exception
*/
@Test
public void testGetBlobInfoErrorSimulation() throws Exception {
BlobId blobId = doPut(partitionId);
ArrayList<BlobId> blobIdList = new ArrayList<BlobId>();
blobIdList.add(blobId);
PartitionRequestInfo partitionRequestInfo = new PartitionRequestInfo(partitionId, blobIdList);
ArrayList<PartitionRequestInfo> partitionRequestInfoList = new ArrayList<PartitionRequestInfo>();
partitionRequestInfoList.add(partitionRequestInfo);
GetRequest getRequest = new GetRequest(1234, "clientId", MessageFormatFlags.BlobInfo, partitionRequestInfoList, GetOption.None);
RequestInfo requestInfo = new RequestInfo(hostname, port, getRequest, replica, null);
ResponseInfo responseInfo = sendAndWaitForResponses(requestInfo);
GetResponse response = responseInfo.getError() == null ? (GetResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse()) : null;
PartitionResponseInfo partitionResponseInfo = response.getPartitionResponseInfoList().get(0);
Assert.assertEquals("GetBlobInfo should succeed.", response.getError(), ServerErrorCode.No_Error);
Assert.assertEquals("GetBlobInfo partitionResponseInfo should succeed.", partitionResponseInfo.getErrorCode(), ServerErrorCode.No_Error);
responseInfo.release();
// inject error for cloud colo.
cloudDestination.setServerErrorForAllRequests(StoreErrorCodes.ID_Not_Found);
getRequest = new GetRequest(1234, "clientId", MessageFormatFlags.BlobInfo, partitionRequestInfoList, GetOption.None);
requestInfo = new RequestInfo(hostname, port, getRequest, replica, null);
responseInfo = sendAndWaitForResponses(requestInfo);
response = responseInfo.getError() == null ? (GetResponse) RouterUtils.mapToReceivedResponse((Response) responseInfo.getResponse()) : null;
partitionResponseInfo = response.getPartitionResponseInfoList().get(0);
Assert.assertEquals("GetBlobInfo responseInfo should have no error.", response.getError(), ServerErrorCode.No_Error);
Assert.assertEquals("GetBlobInfo partitionResponseInfo should be Blob_Not_Found", partitionResponseInfo.getErrorCode(), ServerErrorCode.Blob_Not_Found);
responseInfo.release();
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class Http2Utils method releaseAndCloseStreamChannel.
static RequestInfo releaseAndCloseStreamChannel(Channel streamChannel) {
logger.debug("Stream channel is being closed. Stream: {}, Parent: {}", streamChannel, streamChannel.parent());
RequestInfo requestInfo = streamChannel.attr(Http2NetworkClient.REQUEST_INFO).getAndSet(null);
if (requestInfo != null) {
// REQUEST_INFO is used to indicate if a streamChannel has been released before.
streamChannel.parent().attr(Http2MultiplexedChannelPool.HTTP2_MULTIPLEXED_CHANNEL_POOL).get().release(streamChannel);
}
return requestInfo;
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class Http2ClientResponseHandler method exceptionCaught.
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
http2ClientMetrics.http2StreamExceptionCount.inc();
logger.info("Exception caught in Http2ClientResponseHandler {} {}. Closing stream channel. Cause: ", ctx.channel().hashCode(), ctx.channel(), cause);
RequestInfo requestInfo = releaseAndCloseStreamChannel(ctx.channel());
if (requestInfo != null) {
responseInfoQueue.put(new ResponseInfo(requestInfo, NetworkClientErrorCode.NetworkError, null));
// Will be removed from
}
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class Http2NetworkClient method sendAndPoll.
@Override
public List<ResponseInfo> sendAndPoll(List<RequestInfo> requestsToSend, Set<Integer> requestsToDrop, int pollTimeoutMs) {
List<ResponseInfo> readyResponseInfos = new ArrayList<>();
if (requestsToDrop.size() != 0) {
logger.warn("Number of requestsToDrop: {}", requestsToDrop.size());
http2ClientMetrics.http2RequestsToDropCount.inc(requestsToDrop.size());
for (int correlationId : requestsToDrop) {
Channel streamChannel = correlationIdInFlightToChannelMap.remove(correlationId);
if (streamChannel != null) {
logger.warn("Drop request on streamChannel: {}", streamChannel);
// Drop request just generates a ResponseInfo with TimeoutError to router.
// The stream is still transmitting, but router will ignore ResponseInfo with the same correlationId.
// We need stream reset to cancel the stream in transmitting.
RequestInfo requestInfo = streamChannel.attr(Http2NetworkClient.REQUEST_INFO).get();
if (requestInfo != null) {
readyResponseInfos.add(new ResponseInfo(requestInfo, NetworkClientErrorCode.TimeoutError, null));
}
}
}
}
long sendStartTime = System.currentTimeMillis();
// Send request
http2ClientMetrics.http2ClientSendRate.mark(requestsToSend.size());
for (RequestInfo requestInfo : requestsToSend) {
long streamInitiateTime = System.currentTimeMillis();
long waitingTime = streamInitiateTime - requestInfo.getRequestCreateTime();
http2ClientMetrics.requestToNetworkClientLatencyMs.update(waitingTime);
this.pools.get(InetSocketAddress.createUnresolved(requestInfo.getHost(), requestInfo.getPort().getPort())).acquire().addListener((GenericFutureListener<Future<Channel>>) future -> {
if (future.isSuccess()) {
http2ClientMetrics.http2StreamAcquireTime.update(System.currentTimeMillis() - streamInitiateTime);
long streamAcquiredTime = System.currentTimeMillis();
Channel streamChannel = future.getNow();
correlationIdInFlightToChannelMap.put(requestInfo.getRequest().getCorrelationId(), streamChannel);
streamChannel.attr(REQUEST_INFO).set(requestInfo);
if (!streamChannel.isWritable() || !streamChannel.parent().isWritable()) {
http2ClientMetrics.http2StreamNotWritableCount.inc();
logger.debug("Stream {} {} not writable. BytesBeforeWritable {} {}", streamChannel.hashCode(), streamChannel, streamChannel.bytesBeforeWritable(), streamChannel.parent().bytesBeforeWritable());
}
streamChannel.writeAndFlush(requestInfo.getRequest()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
long writeAndFlushUsedTime = System.currentTimeMillis() - streamAcquiredTime;
http2ClientMetrics.http2StreamWriteAndFlushTime.update(writeAndFlushUsedTime);
requestInfo.setStreamSendTime(System.currentTimeMillis());
if (writeAndFlushUsedTime > http2ClientConfig.http2WriteAndFlushTimeoutMs) {
logger.debug("WriteAndFlush exceeds http2RequestTimeoutMs {}ms, used time: {}ms, stream channel {}", http2ClientConfig.http2WriteAndFlushTimeoutMs, writeAndFlushUsedTime, streamChannel);
if (http2ClientConfig.http2DropRequestOnWriteAndFlushTimeout) {
RequestInfo requestInfoFromChannelAttr = releaseAndCloseStreamChannel(streamChannel);
if (requestInfoFromChannelAttr != null) {
http2ClientResponseHandler.getResponseInfoQueue().put(new ResponseInfo(requestInfo, NetworkClientErrorCode.NetworkError, null));
}
}
}
} else {
http2ClientMetrics.http2StreamWriteAndFlushErrorCount.inc();
logger.warn("Stream {} {} writeAndFlush fail. Cause: {}", streamChannel.hashCode(), streamChannel, future.cause().toString());
RequestInfo requestInfoFromChannelAttr = releaseAndCloseStreamChannel(streamChannel);
if (requestInfoFromChannelAttr != null) {
http2ClientResponseHandler.getResponseInfoQueue().put(new ResponseInfo(requestInfoFromChannelAttr, NetworkClientErrorCode.NetworkError, null));
}
}
}
});
} else {
logger.error("Couldn't acquire stream channel to {}:{} . Cause:", requestInfo.getHost(), requestInfo.getPort().getPort(), future.cause());
requestInfo.getRequest().release();
http2ClientResponseHandler.getResponseInfoQueue().put(new ResponseInfo(requestInfo, NetworkClientErrorCode.NetworkError, null));
}
});
}
http2ClientMetrics.http2ClientSendTime.update(System.currentTimeMillis() - sendStartTime);
http2ClientResponseHandler.getResponseInfoQueue().poll(readyResponseInfos, pollTimeoutMs);
for (ResponseInfo responseInfo : readyResponseInfos) {
correlationIdInFlightToChannelMap.remove(responseInfo.getRequestInfo().getRequest().getCorrelationId());
}
http2ClientMetrics.http2ClientSendRate.mark(readyResponseInfos.size());
http2ClientMetrics.http2ClientSendAndPollTime.update(System.currentTimeMillis() - sendStartTime);
return readyResponseInfos;
}
use of com.github.ambry.network.RequestInfo in project ambry by linkedin.
the class UndeleteOperation method fetchRequests.
/**
* Fetch {@link UndeleteRequest}s to send for the operation.
* @param requestRegistrationCallback the {@link RequestRegistrationCallback} to use for addition of requests that
* need to be sent to the storage server
*/
private void fetchRequests(RequestRegistrationCallback<UndeleteOperation> requestRegistrationCallback) {
Iterator<ReplicaId> replicaIterator = operationTracker.getReplicaIterator();
while (replicaIterator.hasNext()) {
ReplicaId replica = replicaIterator.next();
String hostname = replica.getDataNodeId().getHostname();
Port port = RouterUtils.getPortToConnectTo(replica, routerConfig.routerEnableHttp2NetworkClient);
UndeleteRequest undeleteRequest = createUndeleteRequest();
undeleteRequestInfos.put(undeleteRequest.getCorrelationId(), new UndeleteRequestInfo(time.milliseconds(), replica));
RequestInfo requestInfo = new RequestInfo(hostname, port, undeleteRequest, replica, operationQuotaCharger);
requestRegistrationCallback.registerRequestToSend(this, requestInfo);
replicaIterator.remove();
if (RouterUtils.isRemoteReplica(routerConfig, replica)) {
LOGGER.trace("Making request with correlationId {} to a remote replica {} in {} ", undeleteRequest.getCorrelationId(), replica.getDataNodeId(), replica.getDataNodeId().getDatacenterName());
routerMetrics.crossColoRequestCount.inc();
} else {
LOGGER.trace("Making request with correlationId {} to a local replica {} ", undeleteRequest.getCorrelationId(), replica.getDataNodeId());
}
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).undeleteRequestRate.mark();
}
}
Aggregations