void initiateChunkDeletesIfAny(final String blobIdStr, final String serviceId,
      final QuotaChargeCallback quotaChargeCallback) throws RouterException {
    Callback<GetBlobResult> callback = (GetBlobResult result, Exception exception) -> {
      if (exception != null) {
        // It is expected that these requests will not always succeed. For example, this may have been triggered by a
        // duplicate delete and the blob could have already been hard deleted, so the deserialization can fail, or the
        // blob could have been garbage collected and not found at all and so on.
        logger.trace("Encountered exception when attempting to get chunks of a possibly composite deleted blob {} ",
            blobIdStr, exception);
      } else if (result.getBlobDataChannel() != null) {
        logger.error("Unexpected result returned by background get operation to fetch chunk ids.");
      } else if (result.getBlobChunkIds() != null) {
        List<StoreKey> blobChunkIds = result.getBlobChunkIds();
        List<BackgroundDeleteRequest> deleteRequests = new ArrayList<>(blobChunkIds.size());
        for (StoreKey storeKey : blobChunkIds) {
          logger.trace("Initiating delete of chunk blob: {}", storeKey);
          deleteRequests.add(new BackgroundDeleteRequest(storeKey, serviceId, quotaChargeCallback));
        }
        initiateBackgroundDeletes(deleteRequests);
        if (blobMetadataCache != null) {
          boolean deleteResult = blobMetadataCache.deleteObject(blobIdStr);
          logger.debug("[{}] Issued delete-metadata for blobId = {}, reason = Background delete operation, result = {}",
              blobMetadataCache.getCacheId(), blobIdStr, deleteResult);
        }
      }
      currentBackgroundOperationsCount.decrementAndGet();
    };
    currentOperationsCount.incrementAndGet();
    currentBackgroundOperationsCount.incrementAndGet();
    GetBlobOptions options = new GetBlobOptionsBuilder().operationType(GetBlobOptions.OperationType.All)
        .getOption(GetOption.Include_All)
        .build();
    GetBlobOptionsInternal optionsInternal = new GetBlobOptionsInternal(options, true, routerMetrics.ageAtDelete);
    backgroundDeleter.getBlob(blobIdStr, optionsInternal, callback, quotaChargeCallback);
  }
Initiate the deletes of the data chunks associated with this blobId, if this blob turns out to be a composite
blob. Note that this causes the rate of gets to increase at the servers.
@param blobIdStr the original string of a {@link BlobId} which associated with the possibly composite blob.
@param serviceId the service ID associated with the original delete request.
@param quotaChargeCallback {@link QuotaChargeCallback} object for performing quota compliance checks.
ambry-router/src/main/java/com/github/ambry/router/NonBlockingRouter.java