如何通过StructuredTaskScope通过ScopedValue传播上下文,顺便问下StructuredTaskScope中的MDC ThreadContextMap怎么样?

问题描述 投票:0回答:1

在这种情况下,我需要传播一些状态,如跟踪器/跨度或每个请求的请求上下文。 jdk环境是21.0.1-preview。

我尝试通过通用方式在线程和虚拟线程之间传播任何状态。

喜欢:

class xxxDecorator implements TaskDecorator {
    ...
    public Runnable decorate(@Nonnull Runnable runnable) {
        var bindingsSnapshot = new ScopedValueMap();
        for (var key : keys) {
            bindingsSnapshot.put(key);
        }
        return () -> {
            ScopedValue.Carrier carrier = ScopedValue.where(TRACER_SCOPED_VALUE, bindingsSnapshot.get(TRACER_SCOPED_VALUE));
            for (var key : keys) {
                carrier = carrier.where(key, bindingsSnapshot.get(key));
            }
            carrier.run(runnable);
        };
    }
}

@Slf4j
class ServiceImpl {
    public void xxx() {
        try (var executor = new SimpleAsyncTaskExecutor("pg-")) {
            executor.setVirtualThreads(true);
            var decorator = new PropagatingTaskDecorator();
            executor.setTaskDecorator(decorator);
            executor.setThreadFactory(Thread.ofVirtual().name("v-").factory());

            executor.submit(() -> {
                log.info("{}", xxx); // here log4j2 need print trace info by %X{traceId}
                                     // but how count MDC work for ScopedValue
                                     // up to now, i overwrite the ThreadContextMap and 
                                     // try to split virtual/platform thread for different
                                     // way.
            });
        }
    }
}

有人可以帮我一个忙吗?

java thread-local java-21 virtual-threads scoped-value
1个回答
0
投票

欢迎来到精彩的SO,感谢您提出有趣的问题!

首先,从

ScopeValue
用法的角度来看,我认为您的代码是非常正确的。我无法理解代码中的
bindingsSnapshot
变量和
ScopedValueMap
类,但是如果您声明
TRACER_SCOPED_VALUE
常量,例如

private static final ScopedValue<String> TRACER_SCOPED_VALUE = ScopedValue.newInstance();

,创建一个带有值

Carrier

ScopedValue.Carrier carrier = ScopedValue.where(TRACER_SCOPED_VALUE, "Long live SO!");

,那么在执行任务时,您将能够检索该值:

String value = TRACER_SCOPED_VALUE.get();

因此,我相信,它实现了将状态 (

TRACER_SCOPED_VALUE
) 从“线程”(执行
ServiceImpl.xxx
、执行器的
submit
和装饰器的
decorate
)传播到“虚拟线程”的目标”,由执行者发起。

对于 MDC,(

BasicMDCAdapter
LogbackMDCAdapter
)它使用
ThreadLocal
,而不是当前可用的最新版本中的
ScopeValue
ThreadLocal
ScopeValue
虽然针对类似的问题,但在技术上是不相关的。所以,回答

到目前为止,计数 MDC 如何为 ScopedValue 工作

是“MDS 没有”。

您能否详细说明以下内容:

我覆盖 ThreadContextMap 并尝试以不同的方式分割虚拟/平台线程。

© www.soinside.com 2019 - 2024. All rights reserved.