mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:39:29 +00:00
Refine PropagationContextElement
This commit apply several refinements to PropagationContextElement: - Capture the ThreadLocal when instantiating the PropagationContextElement in order to support dispatchers switching threads - Remove the constructor parameter which is not idiomatic and breaks the support when switching threads, and use instead the updateThreadContext(context: CoroutineContext) parameter - Make the kotlinx-coroutines-reactor dependency optional - Make the properties private The Javadoc and tests are also updated to use the `Dispatchers.IO + PropagationContextElement()` pattern performed outside of the suspending lambda, which is the typical use case. Closes gh-35469
This commit is contained in:
@@ -257,29 +257,20 @@ For Kotlin `Flow`, a `Flow<T>.transactional` extension is provided.
|
||||
Spring applications are xref:integration/observability.adoc[instrumented with Micrometer for Observability support].
|
||||
For tracing support, the current observation is propagated through a `ThreadLocal` for blocking code,
|
||||
or the Reactor `Context` for reactive pipelines. But the current observation also needs to be made available
|
||||
in the execution context of a suspended function. Without that, the current "traceId" will not be automatically prepended
|
||||
to logged statements from coroutines.
|
||||
in the execution context of a suspended function. Without that, the current "traceId" will not be automatically
|
||||
prepended to logged statements from coroutines.
|
||||
|
||||
The `org.springframework.core.PropagationContextElement` operator generally ensures that the
|
||||
The {spring-framework-api-kdoc}/spring-core/org.springframework.core/-propagation-context-element/index.html[`PropagationContextElement`] operator generally ensures that the
|
||||
{micrometer-context-propagation-docs}/[Micrometer Context Propagation library] works with Kotlin Coroutines.
|
||||
|
||||
The `PropagationContextElement` requires the following dependencies:
|
||||
It requires the `io.micrometer:context-propagation` dependency and optionally the
|
||||
`org.jetbrains.kotlinx:kotlinx-coroutines-reactor` one.
|
||||
|
||||
`build.gradle.kts`
|
||||
[source,kotlin,indent=0]
|
||||
----
|
||||
dependencies {
|
||||
implementation("io.micrometer:context-propagation:${contextPropagationVersion}")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutinesVersion}")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:${coroutinesVersion}")
|
||||
}
|
||||
----
|
||||
|
||||
Applications can then use the `PropagationContextElement` operator to connect the `currentCoroutineContext()`
|
||||
Applications can then use the `PropagationContextElement` to augment the `CoroutineContext`
|
||||
with the context propagation mechanism:
|
||||
|
||||
include-code::./ContextPropagationSample[tag=context,indent=0]
|
||||
|
||||
Here, assuming that Micrometer Tracing is configured, the resulting logging statement
|
||||
will show the current "traceId" and unlock better observability for your application.
|
||||
Here, assuming that Micrometer Tracing is configured, the resulting logging statement will show the current "traceId"
|
||||
and unlock better observability for your application.
|
||||
|
||||
|
||||
+11
-5
@@ -16,8 +16,9 @@
|
||||
|
||||
package org.springframework.docs.languages.kotlin.coroutines.propagation
|
||||
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.apache.commons.logging.Log
|
||||
import org.apache.commons.logging.LogFactory
|
||||
import org.springframework.core.PropagationContextElement
|
||||
@@ -31,10 +32,15 @@ class ContextPropagationSample {
|
||||
}
|
||||
|
||||
// tag::context[]
|
||||
fun main() {
|
||||
runBlocking(Dispatchers.IO + PropagationContextElement()) {
|
||||
suspendingFunction()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendingFunction() {
|
||||
return withContext(PropagationContextElement(currentCoroutineContext())) {
|
||||
logger.info("Suspending function with traceId")
|
||||
}
|
||||
delay(1)
|
||||
logger.info("Suspending function with traceId")
|
||||
}
|
||||
// end::context[]
|
||||
}
|
||||
Reference in New Issue
Block a user