private void completeReplicateRequest(NetworkRequest request, ReplicateBlobRequest replicateBlobRequest,
      ServerErrorCode errorCode, long startProcessTime) throws InterruptedException {
    ReplicateBlobResponse response =
        new ReplicateBlobResponse(replicateBlobRequest.getCorrelationId(), replicateBlobRequest.getClientId(),
            errorCode);
    long requestQueueTime = startProcessTime - request.getStartTimeInMs();
    long processingTime = SystemTime.getInstance().milliseconds() - startProcessTime;
    long totalTimeSpent = requestQueueTime + processingTime;

    if (notification != null && errorCode == ServerErrorCode.NoError) {
      notification.onBlobReplicaReplicated(currentNode.getHostname(), currentNode.getPort(),
          replicateBlobRequest.getBlobId().getID(), BlobReplicaSourceType.PRIMARY);
    }

    publicAccessLogger.info("{} {} processingTime {}", replicateBlobRequest, response, processingTime);
    // Update request metrics.
    RequestMetricsUpdater metricsUpdater = new RequestMetricsUpdater(requestQueueTime, processingTime, 0, 0, false);
    replicateBlobRequest.accept(metricsUpdater);
    requestResponseChannel.sendResponse(response, request,
        new ServerNetworkResponseMetrics(metrics.replicateBlobResponseQueueTimeInMs, metrics.replicateBlobSendTimeInMs,
            metrics.replicateBlobTotalTimeInMs, null, null, totalTimeSpent));
  }
Get the Blob from the remote replica
@param replicateBlobRequest the {@link ReplicateBlobRequest}
@return a pair of the {@link ServerErrorCode} and the {@link GetResponse}.
ambry-server/src/main/java/com/github/ambry/server/AmbryRequests.java