Source:
public void run() { try { while (currentPutCount.get() < totalPutCount) { long startTimeInNs = SystemTime.getInstance().nanoseconds(); int burstCount = threadLocalRandom.nextInt(maxParallelRequest) + 1; logger.info("PutThread producing " + burstCount + " times "); final CountDownLatch countDownLatch = new CountDownLatch(burstCount); final AtomicInteger failureCount = new AtomicInteger(0); for (int j = 0; j < burstCount; j++) { Callback<Pair<String, byte[]>> callback = new Callback<Pair<String, byte[]>>() { long callBakStartTimeInNs = SystemTime.getInstance().nanoseconds(); @Override public void onCompletion(Pair<String, byte[]> result, Exception exception) { long callBackendTimeInNs = SystemTime.getInstance().nanoseconds(); metricsCollector.updateLatency(callBackendTimeInNs - callBakStartTimeInNs); if (exception == null) { if (currentPutCount.get() < totalPutCount) { generatedBlobAccessInfos.add(new BlobAccessInfo(result.getFirst(), result.getSecond())); currentPutCount.incrementAndGet(); } } else { logger.error("PutBlob failed with ", exception); failureCount.incrementAndGet(); } countDownLatch.countDown(); } }; putHelper.putBlob(callback); } countDownLatch.await(5, TimeUnit.MINUTES); metricsCollector.updateTimePassedSoFar(SystemTime.getInstance().nanoseconds() - startTimeInNs); if (failureCount.get() > maxFailuresPerPutBatchToStopPuts) { logger.error(failureCount.get() + " failures during this batch, hence exiting the Put Thread"); break; } Thread.sleep(threadLocalRandom.nextLong(sleepTimeBetweenBatchPutsInMs)); } } catch (InterruptedException ex) { logger.error("InterruptedException in putThread ", ex); } finally { putComplete.set(true); metricsCollector.reportMetrics(); } logger.info( "Exiting Producer. Current Put Count " + currentPutCount.get() + ", total Put Count " + totalPutCount); }

Target:
public void run() { try { while (currentPutCount.get() < totalPutCount) { long startTimeInMs = SystemTime.getInstance().milliseconds(); int burstCount = threadLocalRandom.nextInt(maxParallelRequest) + 1; logger.info("PutThread producing " + burstCount + " times "); final CountDownLatch countDownLatch = new CountDownLatch(burstCount); final AtomicInteger failureCount = new AtomicInteger(0); for (int j = 0; j < burstCount; j++) { Callback<Pair<String, byte[]>> callback = new Callback<Pair<String, byte[]>>() { @Override public void onCompletion(Pair<String, byte[]> result, Exception exception) { if (exception == null) { if (currentPutCount.get() < totalPutCount) { generatedBlobAccessInfos.add(new BlobAccessInfo(result.getFirst(), result.getSecond())); currentPutCount.incrementAndGet(); } } else { logger.error("PutBlob failed with ", exception); failureCount.incrementAndGet(); } countDownLatch.countDown(); } }; putHelper.putBlob(callback, metricsCollector); } countDownLatch.await(5, TimeUnit.MINUTES); metricsCollector.updateTimePassedSoFar(SystemTime.getInstance().nanoseconds() - startTimeInMs); if (failureCount.get() > maxFailuresPerPutBatchToStopPuts) { logger.error(failureCount.get() + " failures during this batch, hence exiting the Put Thread"); break; } Thread.sleep(threadLocalRandom.nextLong(sleepTimeBetweenBatchPutsInMs)); } } catch (InterruptedException ex) { logger.error("InterruptedException in putThread ", ex); } finally { putComplete.set(true); metricsCollector.reportMetrics(); } logger.info( "Exiting Producer. Current Put Count " + currentPutCount.get() + ", total Put Count " + totalPutCount); }