use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class TtlUpdateOperation method handleResponse.
/**
* Handles a response for a TTL update operation. It determines whether the request was successful and updates
* operation tracker. For the same operation, it is possible that different {@link ServerErrorCode} are received from
* different replicas. These error codes are eventually resolved to a single {@link RouterErrorCode}.
* @param responseInfo The {@link ResponseInfo} to be handled.
* @param ttlUpdateResponse The {@link TtlUpdateResponse} associated with this response.
*/
void handleResponse(ResponseInfo responseInfo, TtlUpdateResponse ttlUpdateResponse) {
TtlUpdateRequest ttlUpdateRequest = (TtlUpdateRequest) responseInfo.getRequestInfo().getRequest();
TtlUpdateRequestInfo ttlUpdateRequestInfo = ttlUpdateRequestInfos.remove(ttlUpdateRequest.getCorrelationId());
// metric is updated here, as corresponding metrics have been updated when the request was timed out.
if (ttlUpdateRequestInfo == null) {
return;
}
ReplicaId replica = ttlUpdateRequestInfo.replica;
long requestLatencyMs = time.milliseconds() - ttlUpdateRequestInfo.startTimeMs;
routerMetrics.routerRequestLatencyMs.update(requestLatencyMs);
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).ttlUpdateRequestLatencyMs.update(requestLatencyMs);
// Check the error code from NetworkClient.
if (responseInfo.getError() != null) {
LOGGER.debug("TtlUpdateRequest with response correlationId {} timed out for replica {} ", ttlUpdateRequest.getCorrelationId(), replica.getDataNodeId());
onErrorResponse(replica, new RouterException("Operation timed out because of " + responseInfo.getError() + " at DataNode " + responseInfo.getDataNode(), RouterErrorCode.OperationTimedOut));
} else {
if (ttlUpdateResponse == null) {
LOGGER.debug("TtlUpdateRequest with response correlationId {} received UnexpectedInternalError on response deserialization for replica {} ", ttlUpdateRequest.getCorrelationId(), replica.getDataNodeId());
onErrorResponse(replica, new RouterException("Response deserialization received an unexpected error", RouterErrorCode.UnexpectedInternalError));
} else {
// not for its original request. We will immediately fail this operation.
if (ttlUpdateResponse.getCorrelationId() != ttlUpdateRequest.getCorrelationId()) {
LOGGER.error("The correlation id in the TtlUpdateResponse {} is not the same as the correlation id in the associated TtlUpdateRequest: {}", ttlUpdateResponse.getCorrelationId(), ttlUpdateRequest.getCorrelationId());
routerMetrics.unknownReplicaResponseError.inc();
onErrorResponse(replica, new RouterException("Received wrong response that is not for the corresponding request.", RouterErrorCode.UnexpectedInternalError));
} else {
ServerErrorCode serverError = ttlUpdateResponse.getError();
if (serverError == ServerErrorCode.No_Error || serverError == ServerErrorCode.Blob_Already_Updated) {
operationTracker.onResponse(replica, TrackedRequestFinalState.SUCCESS);
if (RouterUtils.isRemoteReplica(routerConfig, replica)) {
LOGGER.trace("Cross colo request successful for remote replica {} in {} ", replica.getDataNodeId(), replica.getDataNodeId().getDatacenterName());
routerMetrics.crossColoSuccessCount.inc();
}
} else if (serverError == ServerErrorCode.Disk_Unavailable) {
LOGGER.debug("Replica {} returned Disk_Unavailable for a Ttl update request with response correlationId : {} ", replica.getDataNodeId(), ttlUpdateResponse.getCorrelationId());
operationTracker.onResponse(replica, TrackedRequestFinalState.DISK_DOWN);
setOperationException(new RouterException("Server returned: " + serverError, RouterErrorCode.AmbryUnavailable));
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).ttlUpdateRequestErrorCount.inc();
} else {
LOGGER.debug("Replica {} returned an error {} for a Ttl update request with response correlationId : {} ", replica.getDataNodeId(), serverError, ttlUpdateResponse.getCorrelationId());
RouterErrorCode routerErrorCode = processServerError(serverError);
if (ttlUpdateResponse.getError() == ServerErrorCode.Blob_Authorization_Failure) {
// this is a successful response and one that completes the operation regardless of whether the
// success target has been reached or not.
operationCompleted = true;
}
// any server error code that is not equal to ServerErrorCode.No_Error, the onErrorResponse should be invoked
// because the operation itself doesn't succeed although the response in some cases is successful (i.e. Blob_Deleted)
onErrorResponse(replica, new RouterException("Server returned: " + serverError, routerErrorCode));
}
}
}
}
checkAndMaybeComplete();
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class ServerTestUtil method updateBlobTtl.
/**
* Updates the TTL of the given {@code blobId}
* @param channel the {@link ConnectedChannel} to make the {@link GetRequest} on.
* @param blobId the ID of the blob to TTL update
* @param ts the operation time
* @throws IOException
*/
static void updateBlobTtl(ConnectedChannel channel, BlobId blobId, long ts) throws IOException {
TtlUpdateRequest ttlUpdateRequest = new TtlUpdateRequest(1, "updateBlobTtl", blobId, Utils.Infinite_Time, ts);
DataInputStream stream = channel.sendAndReceive(ttlUpdateRequest).getInputStream();
TtlUpdateResponse ttlUpdateResponse = TtlUpdateResponse.readFrom(stream);
releaseNettyBufUnderneathStream(stream);
assertEquals("Unexpected ServerErrorCode for TtlUpdateRequest", ServerErrorCode.No_Error, ttlUpdateResponse.getError());
}
use of com.github.ambry.protocol.TtlUpdateRequest in project ambry by linkedin.
the class AmbryServerRequestsTest method doTtlUpdate.
// ttlUpdateTest() helpers
/**
* Does a TTL update and checks for success if {@code expectedErrorCode} is {@link ServerErrorCode#No_Error}. Else,
* checks for failure with the code {@code expectedErrorCode}.
* @param correlationId the correlation ID to use in the request
* @param clientId the client ID to use in the request
* @param blobId the blob ID to use in the request
* @param expiresAtMs the expiry time (ms) to use in the request
* @param opTimeMs the operation time (ms) to use in the request
* @param expectedErrorCode the expected {@link ServerErrorCode}
* @throws InterruptedException
* @throws IOException
* @throws MessageFormatException
*/
private void doTtlUpdate(int correlationId, String clientId, BlobId blobId, long expiresAtMs, long opTimeMs, ServerErrorCode expectedErrorCode) throws InterruptedException, IOException, MessageFormatException, StoreException {
TtlUpdateRequest request = new TtlUpdateRequest(correlationId, clientId, blobId, expiresAtMs, opTimeMs);
sendAndVerifyOperationRequest(request, expectedErrorCode, true).release();
if (expectedErrorCode == ServerErrorCode.No_Error) {
verifyTtlUpdate(request.getBlobId(), expiresAtMs, opTimeMs, MockStorageManager.messageWriteSetReceived);
}
}
Aggregations