Simplify WeakMapSuppliers

Also move CleanerTest to PeriodicSchedulingTest
This commit is contained in:
Nikolay Martynov 2020-04-13 17:29:00 -04:00
parent d86093c474
commit 683477bd60
3 changed files with 30 additions and 24 deletions

View File

@ -3,6 +3,8 @@ package datadog.trace.agent.tooling;
import com.blogspot.mydailyjava.weaklockfree.WeakConcurrentMap; import com.blogspot.mydailyjava.weaklockfree.WeakConcurrentMap;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import datadog.common.exec.CommonTaskExecutor;
import datadog.common.exec.CommonTaskExecutor.Task;
import datadog.trace.bootstrap.WeakMap; import datadog.trace.bootstrap.WeakMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -40,15 +42,23 @@ class WeakMapSuppliers {
@Override @Override
public <K, V> WeakMap<K, V> get() { public <K, V> WeakMap<K, V> get() {
final WeakConcurrentMap<K, V> map = new WeakConcurrentMap<>(false, true); final WeakConcurrentMap<K, V> 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); return new Adapter<>(map);
} }
private static class MapCleaner implements Cleaner.Adapter<WeakConcurrentMap> { // Important to use explicit class to avoid implicit hard references to target
private static final MapCleaner CLEANER = new MapCleaner(); private static class MapCleaningTask implements Task<WeakConcurrentMap> {
static final MapCleaningTask INSTANCE = new MapCleaningTask();
@Override @Override
public void clean(final WeakConcurrentMap target) { public void run(final WeakConcurrentMap target) {
target.expungeStaleEntries(); target.expungeStaleEntries();
} }
} }

View File

@ -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.gc.GCUtils
import datadog.trace.util.test.DDSpecification import datadog.trace.util.test.DDSpecification
import spock.lang.Retry import spock.lang.Retry
import spock.lang.Subject
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
@ -13,19 +11,15 @@ import java.util.concurrent.atomic.AtomicInteger
import static java.util.concurrent.TimeUnit.MILLISECONDS import static java.util.concurrent.TimeUnit.MILLISECONDS
@Retry @Retry
class CleanerTest extends DDSpecification { class PeriodicSchedulingTest extends DDSpecification {
@Subject
def cleaner = new Cleaner()
def "test scheduling"() { def "test scheduling"() {
setup: setup:
def latch = new CountDownLatch(2) def latch = new CountDownLatch(2)
def target = new Object() def task = new CommonTaskExecutor.Task<CountDownLatch>() {
def action = new Cleaner.Adapter<Object>() {
@Override @Override
void clean(Object t) { void run(CountDownLatch target) {
latch.countDown() target.countDown()
} }
} }
@ -33,7 +27,7 @@ class CleanerTest extends DDSpecification {
!CommonTaskExecutor.INSTANCE.isShutdown() !CommonTaskExecutor.INSTANCE.isShutdown()
when: when:
cleaner.scheduleCleaning(target, action, 10, MILLISECONDS) CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, latch, 10, 10, MILLISECONDS, "test")
then: then:
latch.await(500, MILLISECONDS) latch.await(500, MILLISECONDS)
@ -43,10 +37,10 @@ class CleanerTest extends DDSpecification {
setup: setup:
def callCount = new AtomicInteger() def callCount = new AtomicInteger()
def target = new WeakReference(new Object()) def target = new WeakReference(new Object())
def action = new Cleaner.Adapter<Object>() { def task = new CommonTaskExecutor.Task<Object>() {
@Override @Override
void clean(Object t) { void run(Object t) {
callCount.incrementAndGet() callCount.countDown()
} }
} }
@ -54,7 +48,7 @@ class CleanerTest extends DDSpecification {
!CommonTaskExecutor.INSTANCE.isShutdown() !CommonTaskExecutor.INSTANCE.isShutdown()
when: when:
cleaner.scheduleCleaning(target.get(), action, 10, MILLISECONDS) CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, target.get(), 10, 10, MILLISECONDS, "test")
GCUtils.awaitGC(target) GCUtils.awaitGC(target)
Thread.sleep(1) Thread.sleep(1)
def snapshot = callCount.get() def snapshot = callCount.get()
@ -67,10 +61,10 @@ class CleanerTest extends DDSpecification {
def "test null target"() { def "test null target"() {
setup: setup:
def callCount = new AtomicInteger() def callCount = new AtomicInteger()
def action = new Cleaner.Adapter<Object>() { def task = new CommonTaskExecutor.Task<Object>() {
@Override @Override
void clean(Object t) { void run(Object t) {
callCount.incrementAndGet() callCount.countDown()
} }
} }
@ -78,7 +72,7 @@ class CleanerTest extends DDSpecification {
!CommonTaskExecutor.INSTANCE.isShutdown() !CommonTaskExecutor.INSTANCE.isShutdown()
when: when:
cleaner.scheduleCleaning(null, action, 10, MILLISECONDS) CommonTaskExecutor.INSTANCE.scheduleAtFixedRate(task, null, 10, 10, MILLISECONDS, "test")
Thread.sleep(11) Thread.sleep(11)
then: then:

View File

@ -2,4 +2,6 @@ apply from: "${rootDir}/gradle/java.gradle"
dependencies { dependencies {
compile deps.slf4j compile deps.slf4j
testCompile project(':utils:test-utils')
} }