Search in sources :

Example 36 with RequestInfo

use of com.github.ambry.network.RequestInfo in project ambry by linkedin.

the class BackgroundDeleter method onResponse.

/**
 * Handle the response from polling the {@link NetworkClient}.
 * @param responseInfoList the list of {@link ResponseInfo} containing the responses.
 */
protected void onResponse(List<ResponseInfo> responseInfoList) {
    for (ResponseInfo responseInfo : responseInfoList) {
        try {
            RequestInfo requestInfo = responseInfo.getRequestInfo();
            if (requestInfo == null) {
                // If requestInfo is null, it means request has been failed previously due to long wait in pending requests
                // queue. The failed request was already handled by one of the managers(PutManager, GetManager, etc). Current
                // response comes from timed-out connection associated with previous request. Router only needs to notify
                // responseHandler to mark the data node resource down.
                DataNodeId dataNodeId = responseInfo.getDataNode();
                responseHandler.onConnectionTimeout(dataNodeId);
            } else {
                long responseReceiveTime = requestInfo.getStreamHeaderFrameReceiveTime();
                if (responseReceiveTime != -1) {
                    routerMetrics.responseReceiveToHandleLatencyMs.update(System.currentTimeMillis() - responseReceiveTime);
                }
                RequestOrResponseType type = ((RequestOrResponse) requestInfo.getRequest()).getRequestType();
                logger.debug("Handling response of type {} for {}", type, requestInfo.getRequest().getCorrelationId());
                switch(type) {
                    case PutRequest:
                        putManager.handleResponse(responseInfo);
                        break;
                    case GetRequest:
                        getManager.handleResponse(responseInfo);
                        break;
                    case DeleteRequest:
                        deleteManager.handleResponse(responseInfo);
                        break;
                    case TtlUpdateRequest:
                        ttlUpdateManager.handleResponse(responseInfo);
                        break;
                    case UndeleteRequest:
                        undeleteManager.handleResponse(responseInfo);
                        break;
                    default:
                        logger.error("Unexpected response type: {} received, discarding", type);
                }
            }
        } catch (Exception e) {
            logger.error("Unexpected error received while handling a response: ", e);
            routerMetrics.operationManagerHandleResponseErrorCount.inc();
        }
    }
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) RequestOrResponseType(com.github.ambry.protocol.RequestOrResponseType) RequestOrResponse(com.github.ambry.protocol.RequestOrResponse) RequestInfo(com.github.ambry.network.RequestInfo) DataNodeId(com.github.ambry.clustermap.DataNodeId) IOException(java.io.IOException)

Example 37 with RequestInfo

use of com.github.ambry.network.RequestInfo in project ambry by linkedin.

the class DeleteManager method handleResponse.

/**
 * Handles responses received for each of the {@link DeleteOperation} within this delete manager.
 * @param responseInfo the {@link ResponseInfo} containing the response.
 */
void handleResponse(ResponseInfo responseInfo) {
    long startTime = time.milliseconds();
    DeleteResponse deleteResponse = RouterUtils.extractResponseAndNotifyResponseHandler(responseHandler, routerMetrics, responseInfo, DeleteResponse::readFrom, DeleteResponse::getError);
    RequestInfo routerRequestInfo = responseInfo.getRequestInfo();
    int correlationId = ((DeleteRequest) routerRequestInfo.getRequest()).getCorrelationId();
    DeleteOperation deleteOperation = correlationIdToDeleteOperation.remove(correlationId);
    // If it is still an active operation, hand over the response. Otherwise, ignore.
    if (deleteOperations.contains(deleteOperation)) {
        boolean exceptionEncountered = false;
        try {
            deleteOperation.handleResponse(responseInfo, deleteResponse);
        } catch (Exception e) {
            exceptionEncountered = true;
            deleteOperation.setOperationException(new RouterException("Delete handleResponse encountered unexpected error", e, RouterErrorCode.UnexpectedInternalError));
        }
        if (exceptionEncountered || deleteOperation.isOperationComplete()) {
            if (deleteOperations.remove(deleteOperation)) {
                onComplete(deleteOperation);
            }
        }
        routerMetrics.deleteManagerHandleResponseTimeMs.update(time.milliseconds() - startTime);
    } else {
        routerMetrics.ignoredResponseCount.inc();
    }
}
Also used : DeleteResponse(com.github.ambry.protocol.DeleteResponse) RequestInfo(com.github.ambry.network.RequestInfo) DeleteRequest(com.github.ambry.protocol.DeleteRequest)

Example 38 with RequestInfo

use of com.github.ambry.network.RequestInfo in project ambry by linkedin.

the class CloudOperationTest method doDirectPut.

/**
 * Do a put directly to the mock servers. This allows for blobs with malformed properties to be constructed.
 * @param blobProperties the {@link BlobProperties} for the blob.
 * @param userMetadata user meta data of the blob.
 * @param blobContent the raw content for the blob to upload (i.e. this can be serialized composite blob metadata or
 *                    an encrypted blob).
 * @return the blob id
 * @throws Exception Any unexpected exception
 */
private BlobId doDirectPut(BlobProperties blobProperties, byte[] userMetadata, ByteBuf blobContent) throws Exception {
    List<PartitionId> writablePartitionIds = mockClusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS);
    PartitionId partitionId = writablePartitionIds.get(random.nextInt(writablePartitionIds.size()));
    BlobId blobId = new BlobId(routerConfig.routerBlobidCurrentVersion, BlobId.BlobIdType.NATIVE, mockClusterMap.getLocalDatacenterId(), blobProperties.getAccountId(), blobProperties.getContainerId(), partitionId, blobProperties.isEncrypted(), BlobId.BlobDataType.DATACHUNK);
    Iterator<MockServer> servers = partitionId.getReplicaIds().stream().map(ReplicaId::getDataNodeId).map(dataNodeId -> mockServerLayout.getMockServer(dataNodeId.getHostname(), dataNodeId.getPort())).iterator();
    ByteBuffer userMetadataBuf = ByteBuffer.wrap(userMetadata);
    while (servers.hasNext()) {
        MockServer server = servers.next();
        PutRequest request = new PutRequest(random.nextInt(), "clientId", blobId, blobProperties, userMetadataBuf.duplicate(), blobContent.retainedDuplicate(), blobContent.readableBytes(), BlobType.DataBlob, null);
        // Make sure we release the BoundedNettyByteBufReceive.
        server.send(request).release();
        request.release();
    }
    // send to Cloud destinations.
    PutRequest request = new PutRequest(random.nextInt(), "clientId", blobId, blobProperties, userMetadataBuf.duplicate(), blobContent.retainedDuplicate(), blobContent.readableBytes(), BlobType.DataBlob, null);
    // Get the cloud replica.
    ReplicaId replica = partitionId.getReplicaIds().get(0);
    Assert.assertEquals("It should be a cloud backed replica.", replica.getReplicaType(), ReplicaType.CLOUD_BACKED);
    String hostname = replica.getDataNodeId().getHostname();
    Port port = new Port(-1, PortType.PLAINTEXT);
    List<RequestInfo> requestList = new ArrayList<>();
    RequestInfo requestInfo = new RequestInfo(hostname, port, request, replica, null);
    requestList.add(requestInfo);
    List<ResponseInfo> responseList = sendAndWaitForResponses(requestList);
    request.release();
    blobContent.release();
    return blobId;
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) Arrays(java.util.Arrays) BlobProperties(com.github.ambry.messageformat.BlobProperties) LocalNetworkClientFactory(com.github.ambry.network.LocalNetworkClientFactory) Random(java.util.Random) StoreErrorCodes(com.github.ambry.store.StoreErrorCodes) ByteBuffer(java.nio.ByteBuffer) GetResponse(com.github.ambry.protocol.GetResponse) Future(java.util.concurrent.Future) PortType(com.github.ambry.network.PortType) Map(java.util.Map) After(org.junit.After) NetworkConfig(com.github.ambry.config.NetworkConfig) NettyByteBufLeakHelper(com.github.ambry.utils.NettyByteBufLeakHelper) Parameterized(org.junit.runners.Parameterized) EnumMap(java.util.EnumMap) Collection(java.util.Collection) Utils(com.github.ambry.utils.Utils) PooledByteBufAllocator(io.netty.buffer.PooledByteBufAllocator) Collectors(java.util.stream.Collectors) BlobInfo(com.github.ambry.messageformat.BlobInfo) RouterConfig(com.github.ambry.config.RouterConfig) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) MockTime(com.github.ambry.utils.MockTime) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) Callback(com.github.ambry.commons.Callback) BlobType(com.github.ambry.messageformat.BlobType) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) ResponseHandler(com.github.ambry.commons.ResponseHandler) NetworkMetrics(com.github.ambry.network.NetworkMetrics) DataInputStream(java.io.DataInputStream) CloudDestinationFactory(com.github.ambry.cloud.CloudDestinationFactory) ServerErrorCode(com.github.ambry.server.ServerErrorCode) RunWith(org.junit.runner.RunWith) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) CloudConfig(com.github.ambry.config.CloudConfig) NettyByteBufDataInputStream(com.github.ambry.utils.NettyByteBufDataInputStream) RequestHandlerPool(com.github.ambry.protocol.RequestHandlerPool) ByteBuf(io.netty.buffer.ByteBuf) LatchBasedInMemoryCloudDestination(com.github.ambry.cloud.LatchBasedInMemoryCloudDestination) LocalRequestResponseChannel(com.github.ambry.network.LocalRequestResponseChannel) PutRequest(com.github.ambry.protocol.PutRequest) NetworkClientFactory(com.github.ambry.network.NetworkClientFactory) Before(org.junit.Before) Properties(java.util.Properties) Iterator(java.util.Iterator) ReplicaType(com.github.ambry.clustermap.ReplicaType) NetworkClient(com.github.ambry.network.NetworkClient) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ByteBufferAsyncWritableChannel(com.github.ambry.commons.ByteBufferAsyncWritableChannel) Test(org.junit.Test) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) LatchBasedInMemoryCloudDestinationFactory(com.github.ambry.cloud.LatchBasedInMemoryCloudDestinationFactory) RequestInfo(com.github.ambry.network.RequestInfo) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) CompositeNetworkClientFactory(com.github.ambry.network.CompositeNetworkClientFactory) ReplicaId(com.github.ambry.clustermap.ReplicaId) Port(com.github.ambry.network.Port) Assert(org.junit.Assert) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) ResponseInfo(com.github.ambry.network.ResponseInfo) Port(com.github.ambry.network.Port) ArrayList(java.util.ArrayList) PutRequest(com.github.ambry.protocol.PutRequest) PartitionId(com.github.ambry.clustermap.PartitionId) RequestInfo(com.github.ambry.network.RequestInfo) ByteBuffer(java.nio.ByteBuffer) ReplicaId(com.github.ambry.clustermap.ReplicaId) BlobId(com.github.ambry.commons.BlobId)

Example 39 with RequestInfo

use of com.github.ambry.network.RequestInfo in project ambry by linkedin.

the class GetBlobOperationTest method testNetworkClientTimeoutAllFailure.

/**
 * Test the case where all requests time out within the SocketNetworkClient.
 * @throws Exception
 */
@Test
public void testNetworkClientTimeoutAllFailure() throws Exception {
    doPut();
    GetBlobOperation op = createOperation(routerConfig, null);
    while (!op.isOperationComplete()) {
        op.poll(requestRegistrationCallback);
        for (RequestInfo requestInfo : requestRegistrationCallback.getRequestsToSend()) {
            ResponseInfo fakeResponse = new ResponseInfo(requestInfo, NetworkClientErrorCode.NetworkError, null);
            op.handleResponse(fakeResponse, null);
            fakeResponse.release();
            if (op.isOperationComplete()) {
                break;
            }
        }
        requestRegistrationCallback.getRequestsToSend().clear();
    }
    // At this time requests would have been created for all replicas, as none of them were delivered,
    // and cross-colo proxying is enabled by default.
    Assert.assertEquals("Must have attempted sending requests to all replicas", replicasCount, correlationIdToGetOperation.size());
    assertFailureAndCheckErrorCode(op, RouterErrorCode.OperationTimedOut);
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) PartitionRequestInfo(com.github.ambry.protocol.PartitionRequestInfo) RequestInfo(com.github.ambry.network.RequestInfo) PutManagerTest(com.github.ambry.router.PutManagerTest) Test(org.junit.Test)

Example 40 with RequestInfo

use of com.github.ambry.network.RequestInfo in project ambry by linkedin.

the class NonBlockingRouterTestBase method testResponseDeserializationError.

/**
 * Test that operations succeed even in the presence of responses that are corrupt and fail to deserialize.
 * @param opHelper the {@link OperationHelper}
 * @param networkClient the {@link SocketNetworkClient}
 * @param blobId the id of the blob to get/delete. For puts, this will be null.
 * @throws Exception
 */
protected void testResponseDeserializationError(OperationHelper opHelper, SocketNetworkClient networkClient, BlobId blobId) throws Exception {
    mockSelectorState.set(MockSelectorState.Good);
    FutureResult futureResult = opHelper.submitOperation(blobId);
    int requestParallelism = opHelper.requestParallelism;
    List<RequestInfo> allRequests = new ArrayList<>();
    Set<Integer> allDropped = new HashSet<>();
    long loopStartTimeMs = SystemTime.getInstance().milliseconds();
    while (allRequests.size() < requestParallelism) {
        if (loopStartTimeMs + AWAIT_TIMEOUT_MS < SystemTime.getInstance().milliseconds()) {
            Assert.fail("Waited too long for requests.");
        }
        opHelper.pollOpManager(allRequests, allDropped);
    }
    List<ResponseInfo> responseInfoList = new ArrayList<>();
    loopStartTimeMs = SystemTime.getInstance().milliseconds();
    do {
        if (loopStartTimeMs + AWAIT_TIMEOUT_MS < SystemTime.getInstance().milliseconds()) {
            Assert.fail("Waited too long for the response.");
        }
        responseInfoList.addAll(networkClient.sendAndPoll(allRequests, allDropped, 10));
        allRequests.clear();
    } while (responseInfoList.size() < requestParallelism);
    // corrupt the first response.
    ByteBuf response = responseInfoList.get(0).content();
    byte b = response.getByte(response.writerIndex() - 1);
    response.setByte(response.writerIndex() - 1, (byte) ~b);
    for (ResponseInfo responseInfo : responseInfoList) {
        opHelper.handleResponse(responseInfo);
    }
    responseInfoList.forEach(ResponseInfo::release);
    allRequests.clear();
    if (testEncryption) {
        opHelper.awaitOpCompletionOrTimeOut(futureResult);
    } else {
        opHelper.pollOpManager(allRequests, allDropped);
    }
    try {
        futureResult.get(AWAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
    } catch (ExecutionException e) {
        Assert.fail("Operation should have succeeded with one corrupt response");
    }
}
Also used : ResponseInfo(com.github.ambry.network.ResponseInfo) ArrayList(java.util.ArrayList) RequestInfo(com.github.ambry.network.RequestInfo) ByteBuf(io.netty.buffer.ByteBuf) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutionException(java.util.concurrent.ExecutionException) HashSet(java.util.HashSet)

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