David Glasser
05/13/2020, 7:45 PMwithSomething
that either can be passed a non-suspend block and can be called from either a suspend or non-suspend block and basically does some sort of try { block() } finally { … }
, and a suspend inline function withSomethingSuspend
that can be passed a suspend block and does a more complex withContext
-based trick to manage the same thing. right now you have to choose to use the correct function name for your context; we made the first function non-inline so that you can’t accidentally call it with a suspend block. is there any way we could have just one function name? or at least declare that the first one’s block can’t be suspend so that we could make it inline?octylFractal
05/13/2020, 7:49 PMsuspend
David Glasser
05/13/2020, 7:50 PMfun <T> withLoggingFields(contextMap: Map<String, Any?>?, block: () -> T): T {
val oldContextMap: Map<String, String>? = MDC.getCopyOfContextMap()
MDC.setContextMap((oldContextMap ?: mapOf()) + (contextMap?.mapValues { it.value.toString() } ?: mapOf()))
return try {
block()
} finally {
if (oldContextMap != null) MDC.setContextMap(oldContextMap) else MDC.clear()
}
}
and
suspend inline fun <T> withLoggingFieldsSuspend(
contextMap: Map<String, Any?>?,
crossinline block: suspend CoroutineScope.() -> T
): T = withContext(
MDCContext((MDC.getCopyOfContextMap() ?: mapOf()) + (contextMap?.mapValues { it.value.toString() } ?: mapOf()))
) { block() }
octylFractal
05/13/2020, 7:57 PMcrossinline
, which will forbid it from being suspend
I thinkDavid Glasser
05/13/2020, 7:58 PMinline
basically?octylFractal
05/13/2020, 7:58 PMDavid Glasser
05/13/2020, 7:59 PMoctylFractal
05/13/2020, 8:00 PMcrossinline
because that implies you're not in the same contextJoe
05/13/2020, 8:00 PMoctylFractal
05/13/2020, 8:01 PMNote that you cannot update MDC context from inside of the coroutine simply using MDC.put. These updates are going to be lost on the next suspension and reinstalled to the MDC context that was captured or explicitly specified in contextMap when this object was created on the next resumption. Use withContext(MDCContext()) { ... } to capture updated map of MDC keys and values for the specified block of code.
David Glasser
05/13/2020, 8:01 PMoctylFractal
05/13/2020, 8:01 PMwithContext
element just stores it into the current thread's thread-localJoe
05/13/2020, 8:02 PMDavid Glasser
05/13/2020, 8:02 PMoctylFractal
05/13/2020, 8:02 PMDavid Glasser
05/13/2020, 8:04 PMJoe
05/13/2020, 8:10 PM