diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java index f579210d33..2e1a019c66 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java @@ -3,6 +3,8 @@ package datadog.trace.agent.tooling; import com.blogspot.mydailyjava.weaklockfree.WeakConcurrentMap; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.MapMaker; +import datadog.common.exec.CommonTaskExecutor; +import datadog.common.exec.CommonTaskExecutor.Task; import datadog.trace.bootstrap.WeakMap; import java.util.concurrent.TimeUnit; @@ -40,15 +42,23 @@ class WeakMapSuppliers { @Override public WeakMap get() { final WeakConcurrentMap map = new WeakConcurrentMap<>(false, true); - cleaner.scheduleCleaning(map, MapCleaner.CLEANER, CLEAN_FREQUENCY_SECONDS, TimeUnit.SECONDS); + CommonTaskExecutor.INSTANCE.scheduleAtFixedRate( + MapCleaningTask.INSTANCE, + map, + CLEAN_FREQUENCY_SECONDS, + CLEAN_FREQUENCY_SECONDS, + TimeUnit.SECONDS, + "cleaner for " + map); return new Adapter<>(map); } - private static class MapCleaner implements Cleaner.Adapter { - private static final MapCleaner CLEANER = new MapCleaner(); + // Important to use explicit class to avoid implicit hard references to target + private static class MapCleaningTask implements Task { + + static final MapCleaningTask INSTANCE = new MapCleaningTask(); @Override - public void clean(final WeakConcurrentMap target) { + public void run(final WeakConcurrentMap target) { target.expungeStaleEntries(); } } diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy b/utils/thread-utils/src/test/groovy/datadog/common/exec/PeriodicSchedulingTest.groovy similarity index 60% rename from dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy rename to utils/thread-utils/src/test/groovy/datadog/common/exec/PeriodicSchedulingTest.groovy index d05496f956..c9dad5899c 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy +++ b/utils/thread-utils/src/test/groovy/datadog/common/exec/PeriodicSchedulingTest.groovy @@ -1,10 +1,8 @@ -package datadog.trace.agent.tooling +package datadog.common.exec -import datadog.common.exec.CommonTaskExecutor import datadog.trace.util.gc.GCUtils import datadog.trace.util.test.DDSpecification import spock.lang.Retry -import spock.lang.Subject import java.lang.ref.WeakReference import java.util.concurrent.CountDownLatch @@ -13,19 +11,15 @@ import java.util.concurrent.atomic.AtomicInteger import static java.util.concurrent.TimeUnit.MILLISECONDS @Retry -class CleanerTest extends DDSpecification { - - @Subject - def cleaner = new Cleaner() +class PeriodicSchedulingTest extends DDSpecification { def "test scheduling"() { setup: def latch = new CountDownLatch(2) - def target = new Object() - def action = new Cleaner.Adapter() { + def task = new CommonTaskExecutor.Task() { @Override - void clean(Object t) { - latch.countDown() + void run(CountDownLatch target) { + target.countDown() } } @@ -33,7 +27,7 @@ class CleanerTest extends DDSpecification { !CommonTaskExecutor.INSTANCE.isShutdown() when: - cleaner.scheduleCleaning(target, action, 10, MILLISECONDS) + CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, latch, 10, 10, MILLISECONDS, "test") then: latch.await(500, MILLISECONDS) @@ -43,10 +37,10 @@ class CleanerTest extends DDSpecification { setup: def callCount = new AtomicInteger() def target = new WeakReference(new Object()) - def action = new Cleaner.Adapter() { + def task = new CommonTaskExecutor.Task() { @Override - void clean(Object t) { - callCount.incrementAndGet() + void run(Object t) { + callCount.countDown() } } @@ -54,7 +48,7 @@ class CleanerTest extends DDSpecification { !CommonTaskExecutor.INSTANCE.isShutdown() when: - cleaner.scheduleCleaning(target.get(), action, 10, MILLISECONDS) + CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, target.get(), 10, 10, MILLISECONDS, "test") GCUtils.awaitGC(target) Thread.sleep(1) def snapshot = callCount.get() @@ -67,10 +61,10 @@ class CleanerTest extends DDSpecification { def "test null target"() { setup: def callCount = new AtomicInteger() - def action = new Cleaner.Adapter() { + def task = new CommonTaskExecutor.Task() { @Override - void clean(Object t) { - callCount.incrementAndGet() + void run(Object t) { + callCount.countDown() } } @@ -78,7 +72,7 @@ class CleanerTest extends DDSpecification { !CommonTaskExecutor.INSTANCE.isShutdown() when: - cleaner.scheduleCleaning(null, action, 10, MILLISECONDS) + CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, null, 10, 10, MILLISECONDS, "test") Thread.sleep(11) then: diff --git a/utils/thread-utils/thread-utils.gradle b/utils/thread-utils/thread-utils.gradle index 29bb468d6e..d78196f16b 100644 --- a/utils/thread-utils/thread-utils.gradle +++ b/utils/thread-utils/thread-utils.gradle @@ -2,4 +2,6 @@ apply from: "${rootDir}/gradle/java.gradle" dependencies { compile deps.slf4j + + testCompile project(':utils:test-utils') }