Search in sources :

Example 6 with RequestInfo

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();
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) PartitionResponseInfo(com.github.ambry.protocol.PartitionResponseInfo) GetResponse(com.github.ambry.protocol.GetResponse) TtlUpdateResponse(com.github.ambry.protocol.TtlUpdateResponse) UndeleteResponse(com.github.ambry.protocol.UndeleteResponse) DeleteResponse(com.github.ambry.protocol.DeleteResponse) PutResponse(com.github.ambry.protocol.PutResponse) Response(com.github.ambry.protocol.Response) GetRequest(com.github.ambry.protocol.GetRequest) ArrayList(java.util.ArrayList) PartitionResponseInfo(com.github.ambry.protocol.PartitionResponseInfo) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) RequestInfo(com.github.ambry.network.RequestInfo) BlobId(com.github.ambry.commons.BlobId) GetResponse(com.github.ambry.protocol.GetResponse) Test(org.junit.Test)

Example 7 with RequestInfo

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;
}
Also used : RequestInfo(com.github.ambry.network.RequestInfo)

Example 8 with 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
    }
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) RequestInfo(com.github.ambry.network.RequestInfo)

Example 9 with RequestInfo

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;
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) ResponseInfo(com.github.ambry.network.ResponseInfo) AttributeKey(io.netty.util.AttributeKey) Http2ClientConfig(com.github.ambry.config.Http2ClientConfig) DataNodeId(com.github.ambry.clustermap.DataNodeId) LoggerFactory(org.slf4j.LoggerFactory) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NetworkClientErrorCode(com.github.ambry.network.NetworkClientErrorCode) Http2StreamFrameToHttpObjectCodec(io.netty.handler.codec.http2.Http2StreamFrameToHttpObjectCodec) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Map(java.util.Map) Http2Utils(com.github.ambry.network.http2.Http2Utils) EventLoopGroup(io.netty.channel.EventLoopGroup) Logger(org.slf4j.Logger) SSLFactory(com.github.ambry.commons.SSLFactory) ChannelInitializer(io.netty.channel.ChannelInitializer) NetworkClient(com.github.ambry.network.NetworkClient) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) Set(java.util.Set) InetSocketAddress(java.net.InetSocketAddress) RequestInfo(com.github.ambry.network.RequestInfo) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) List(java.util.List) ChannelPool(io.netty.channel.pool.ChannelPool) ChannelPoolMap(io.netty.channel.pool.ChannelPoolMap) Future(io.netty.util.concurrent.Future) HttpObjectAggregator(io.netty.handler.codec.http.HttpObjectAggregator) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) ArrayList(java.util.ArrayList) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) RequestInfo(com.github.ambry.network.RequestInfo) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Example 10 with RequestInfo

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();
    }
}
Also used : Port(com.github.ambry.network.Port) UndeleteRequest(com.github.ambry.protocol.UndeleteRequest) RequestInfo(com.github.ambry.network.RequestInfo) ReplicaId(com.github.ambry.clustermap.ReplicaId)

Aggregations

RequestInfo (com.github.ambry.network.RequestInfo)45 ResponseInfo (com.github.ambry.network.ResponseInfo)31 ArrayList (java.util.ArrayList)22 Test (org.junit.Test)14 GetResponse (com.github.ambry.protocol.GetResponse)12 PartitionRequestInfo (com.github.ambry.protocol.PartitionRequestInfo)11 PutResponse (com.github.ambry.protocol.PutResponse)10 ReplicaId (com.github.ambry.clustermap.ReplicaId)8 BlobId (com.github.ambry.commons.BlobId)8 Port (com.github.ambry.network.Port)8 PartitionResponseInfo (com.github.ambry.protocol.PartitionResponseInfo)7 BlobProperties (com.github.ambry.messageformat.BlobProperties)6 TtlUpdateResponse (com.github.ambry.protocol.TtlUpdateResponse)6 NettyByteBufDataInputStream (com.github.ambry.utils.NettyByteBufDataInputStream)6 DataInputStream (java.io.DataInputStream)6 DeleteResponse (com.github.ambry.protocol.DeleteResponse)5 GetRequest (com.github.ambry.protocol.GetRequest)5 UndeleteResponse (com.github.ambry.protocol.UndeleteResponse)5 InMemAccountService (com.github.ambry.account.InMemAccountService)4 LoggingNotificationSystem (com.github.ambry.commons.LoggingNotificationSystem)4