Skip to content

Commit db78e70

Browse files
authored
Skip removing stale entries when runnin on virtual thread (#18113)
1 parent f2df851 commit db78e70

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/cache/weaklockfree/AbstractWeakConcurrentMap.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ protected V defaultValue(K key) {
236236

237237
/** Cleans all unused references. */
238238
public static void expungeStaleEntries() {
239+
// Skip expunging stale entries if we are running on a virtual thread.
240+
// See https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/17847
241+
// Stale entries are also expunged from the background thread, see the runCleanup method below.
242+
if (ThreadUtil.isVirtualThread(Thread.currentThread())) {
243+
return;
244+
}
245+
239246
Reference<?> reference;
240247
while ((reference = REFERENCE_QUEUE.poll()) != null) {
241248
removeWeakKey((WeakKey<?>) reference);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.api.internal.cache.weaklockfree;
7+
8+
import javax.annotation.Nullable;
9+
10+
class ThreadUtil {
11+
12+
@Nullable private static final Class<?> virtualThreadClass = findVirtualThreadClass();
13+
14+
@Nullable
15+
private static Class<?> findVirtualThreadClass() {
16+
try {
17+
return Class.forName("java.lang.BaseVirtualThread");
18+
} catch (ClassNotFoundException e) {
19+
return null;
20+
}
21+
}
22+
23+
static boolean isVirtualThread(Thread thread) {
24+
return virtualThreadClass != null && virtualThreadClass.isInstance(thread);
25+
}
26+
27+
private ThreadUtil() {}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.api.internal.cache.weaklockfree;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import org.junit.jupiter.api.Test;
11+
import org.junit.jupiter.api.condition.EnabledForJreRange;
12+
import org.junit.jupiter.api.condition.JRE;
13+
14+
class ThreadUtilTest {
15+
16+
@Test
17+
@EnabledForJreRange(min = JRE.JAVA_21)
18+
void isVirtualThread() throws Exception {
19+
assertThat(ThreadUtil.isVirtualThread(new Thread())).isFalse();
20+
Object builder = Thread.class.getMethod("ofVirtual").invoke(null);
21+
Thread thread =
22+
(Thread)
23+
Class.forName("java.lang.Thread$Builder$OfVirtual")
24+
.getMethod("unstarted", Runnable.class)
25+
.invoke(builder, (Runnable) () -> {});
26+
assertThat(ThreadUtil.isVirtualThread(thread)).isTrue();
27+
}
28+
}

0 commit comments

Comments
 (0)