Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Commit

Permalink
Adding JavaDoc on BatcherReference
Browse files Browse the repository at this point in the history
  • Loading branch information
rahulKQL committed Aug 3, 2019
1 parent 71c3c46 commit e7ac05b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
29 changes: 19 additions & 10 deletions gax/src/main/java/com/google/api/gax/batching/v2/BatcherImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ boolean isCancelled() {
}
}

/**
* On every Batcher allocation this class will check for garbage collected batchers that were
* never closed and emit warning logs.
*/
@VisibleForTesting
static final class BatcherReference extends WeakReference<BatcherImpl> {

Expand All @@ -333,6 +337,8 @@ static final class BatcherReference extends WeakReference<BatcherImpl> {

BatcherReference(BatcherImpl referent) {
super(referent, refQueue);
// allocationSite is softReference to make it garbage collectible, but delay it as long as
// possible as BatcherReference can only be weakly referred.
allocationSite =
new SoftReference<>(
ENABLE_ALLOCATION_TRACKING
Expand Down Expand Up @@ -361,6 +367,16 @@ private void clearInternal() {
allocationSite.clear();
}

/**
* It performs below tasks:
*
* <ul>
* <li>Check each batcher registered on refQueue while initialization.
* <li>Unregister them from refQueue.
* <li>If close() is not called on the batcher, then emits log with possible allocationSite.
* <li>Keeps track of number of batcher on which close() is not called.
* </ul>
*/
@VisibleForTesting
static int cleanQueue() {
BatcherReference ref;
Expand All @@ -370,16 +386,9 @@ static int cleanQueue() {
ref.clearInternal(); // technically the reference is gone already.
if (!ref.closed) {
orphanedBatchers++;
Level level = Level.SEVERE;
if (LOG.isLoggable(level)) {
String message =
"*~*~*~ Batcher was not closed properly!!! ~*~*~*"
+ System.getProperty("line.separator")
+ " Make sure to call close().";
LogRecord lr = new LogRecord(level, message);
lr.setLoggerName(LOG.getName());
lr.setThrown(maybeAllocationSite);
LOG.log(lr);
if (LOG.isLoggable(Level.SEVERE)) {
String message = "Batcher was not closed properly!!! Make sure to call close().";
LOG.log(Level.SEVERE, message, maybeAllocationSite);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,32 @@ public boolean isLoggable(LogRecord record) {
}
}

@Test
public void test() throws InterruptedException {
underTest =
new BatcherImpl<>(
SQUARER_BATCHING_DESC_V2,
callLabeledIntSquarer,
labeledIntList,
batchingSettings,
EXECUTOR);
underTest = null;

// That *should* have been the last reference. Try to reclaim it.
boolean success = false;
for (int retry = 0; retry < 3; retry++) {
System.gc();
System.runFinalization();
int orphans = BatcherReference.cleanQueue();
if (orphans == 1) {
success = true;
break;
}
// Validates that there are no other batcher instance present while GC cleanup.
assertWithMessage("unexpected extra orphans").that(orphans).isEqualTo(0);
Thread.sleep(100L * (1L << retry));
}
}
private void testElementTriggers(BatchingSettings settings) throws Exception {
underTest =
new BatcherImpl<>(
Expand Down

0 comments on commit e7ac05b

Please sign in to comment.