HI Team, Our codebase is in Kotlin and we are usin...
# server
s
HI Team, Our codebase is in Kotlin and we are using OpenTracing library for distributed tracing. We have implemented our custom
ThreadContextElement
as described in the documentation. The problem is we are having memory leak [heap dump shows that opentracing lib objects being leaked] when we use different dispatchers in the flow. For example, in the beginning of the process Step 1 ->
rxCompletable() // default dispatcher
Step 2 -> Use another dispatcher for a network call
withContext(<http://Dispatchers.IO|Dispatchers.IO> + CustomThreadContextElement())
^^ when we switch dispatcher like this we always get memory leak. As long as the entire flow is on one dispatcher we don't get memory leak. Any thoughts here? I am also seeing this CopyableThreadContextElement - should we be using this ? I am not clear on the example provided in the documentation especially the line
Copy code
return CopyForChildCoroutineElement(traceThreadLocal.get())
Where is this
CopyForChildCoroutineElement
class is from?
o
No idea what might be causing your memory leak, but you'd use
CopyableThreadContextElement
for a coroutine-local context. The documentation you were seeing is inaccurate. Here is a PR with a fix (merged, not yet released): https://github.com/Kotlin/kotlinx.coroutines/pull/3157/files
s
@Oliver.O Thank you for clarifying on CopyableThreadContextElement and the examples. Reading more about this on different issue particularly this PR, https://github.com/Kotlin/kotlinx.coroutines/pull/1577/files Do you think this could be our problem? Meaning we might have to set the ThreadLocal involved in our use case [https://www.javadoc.io/doc/io.opentracing/opentracing-util/0.31.0/io/opentracing/util/ThreadLocalScope.html] to NULL at the main dispatcher before we switch to different dispatcher so that when the context moves out to main
restoreThreadContext
gets called
o
The PR you are referring to has been merged, so my understanding is that 
ThreadContextElement
 is always restored properly. I doubt that it is possible to give some generic advice in a multithreading scenario like this, but things you might want to look at (referring to the example on Thread-local data in the docs) include: • Is your 
ThreadLocal
 initialized and inserted into the initial coroutine context before using it for the first time, e.g. via as in 
withContext(threadLocal.asContextElement(value = "launch"))
? • Is your 
ThreadLocal
 mutated once set? • If your 
ThreadLocal
 points to a mutable box, is the latter thread-safe? • Is your 
ThreadLocal
 used exclusively within coroutines (including code called from a coroutine)? • Is your 
ThreadContextElement
 present in every coroutine context? • Do you use ensurePresent to check this?
🙏 1
113 Views