![](/img/trans.png)
[英]How to rewrite the code to use Kotlin's kotlinx-coroutines-jdk8?
[英]How to share MDC context between threads in multimodule project in kotlin - kotlinx.coroutines.slf4j
我有一個多模塊項目,我希望有一個上下文可以通過不同的模塊共享。
在我的核心模塊(它們都依賴於此)中,我創建了一個 class 來使用 org.slf4j.MDC 管理上下文,它有兩個函數,一個用於在上下文 (logContext) 中存儲屬性,另一個用於獲取上下文(get上下文)
import jakarta.inject.Singleton
import kotlinx.coroutines.slf4j.MDCContextMap
import mu.KotlinLogging
import org.slf4j.MDC
private val logger = KotlinLogging.logger {}
@Singleton
class LoggingContext {
companion object {
fun logContext(name: String, id: String) {
MDC.put("name", name)
MDC.put("id", id)
logger.info { "Companion object - logContext: ${MDC.getCopyOfContextMap()}" }
}
fun getContext(): MDCContextMap {
logger.info { "Companion object - getContext: ${MDC.getCopyOfContextMap()}" }
return MDC.getCopyOfContextMap()
}
}
}
問題如下:
我有一個完整的模塊,其中有一個 controller,我想在上下文中存儲來自請求的name
和id
。 為此,我只需在我的 controller 代碼中添加以下行:
logContext("request_name", "request_id")
在 controller 代碼中(在 controller 模塊中),如果我調用getContext()
function,我將獲得剛剛從請求中保存的屬性。 直到這里一切都很好✅
❌ 但是,如果我嘗試這樣做,從另一個模塊獲取上下文,例如,從存儲庫模塊(它是項目中的一個全新模塊)調用getContext()
function,我得到一個 null。那里根本沒有上下文。
我假設是因為,當我試圖從另一個模塊獲取上下文時,它是另一個線程,並且上下文不在整個項目中共享。
更新:為了提供更多上下文,流程如下:
@Get(PATH_GLOBAL)
suspend fun getGlobal(
@PathVariable name: String,
@PathVariable id: String,
httpRequest: HttpRequest<*>,
): HttpResponse<Resource> {
LoggingContext.logContext(name, id)
...
// invoke repository
return readOperation.execute(trigger).fold(...)
}
override suspend fun readConfiguration(...): {
logger.trace { "Reading configuration from repository" }
val entity = configurationDataRepository.findBy(...)
logger.info { "ConfigurationDataRepositoryImpl - readConfiguration4: ${MDC.getCopyOfContextMap()}" }
withContext(MDCContext()) {
logger.info { "ConfigurationDataRepositoryImpl - readConfiguration1: ${MDC.getCopyOfContextMap()}" }
}
return ...
}
我嘗試添加withContext(MDCContext()){...}
但在使用和不使用 withContext 調用getContext()
function 時我得到了withContext...
那么,如何將上下文設置為在所有模塊內共享?
非常感謝您的幫助:)
顯然,解決方案就像在設置 MDC 上下文后立即添加withContext(MDCContext())
一樣簡單,以保留 MDC 上下文。
所以,就我而言,我必須像這樣用之前的 function 包裝我的 controller:
@Get(PATH_GLOBAL)
suspend fun getGlobal(
@PathVariable name: String,
@PathVariable id: String,
httpRequest: HttpRequest<*>,
): HttpResponse<Resource> {
LoggingContext.logContext(name, id)
// Add withContext(MDCContext()) right after setting the Context
return withContext(MDCContext()) {
...
// invoke repository
readOperation.execute(trigger).fold(...)
}
}
這對我行得通!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.