-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Moved from discussion #22749
Question
From @srprash
Hi,
I have a sample ASPNetCore webapp which uses EFCore to add or retrieve users to a postgres db. In addition to this, I'm using AWS X-Ray .Net SDK to trace these operations by adding the EFInterceptor
along with a custom empty MyDbCommandInterceptor
. I'm using the empty interceptor for simplicity. The issue happens with any interceptor used with the EFInterceptor
.
The AWS X-Ray SDK uses AsyncLocal
to store the trace context of the app. When I use just use one of the interceptors, everything works fine. However, when both the interceptors are used together, the trace context gets messed up and becomes inconsistent across threads for async calls involving ExecuteReaderAsync
. The interceptors work fine together for any synchronous operation to the db.
I've opened a related issue on X-Ray SDK's repo with more details pertaining to the error on the SDK but while digging into the cause of the problem, I established that the issue is with AsyncLocal not being consistent for threads invoking ReaderExecutingAsync
and ReaderExecutedAsync
methods before and after an async call to my postgres db.
I wonder if using multiple DbCommandInterceptor
s has an impact on separate threads and their thread local storage. Also, ReaderExecutingAsync
and ReaderExecutedAsync
methods seem to execute on different threads. Is there a way to ensure they run on same thread or to propagate a context between these methods?
I'm hoping to get some direction from this discussion to investigate the problem further and resolve it. Any help is greatly appreciated :)
Replies
From @roji
@srprash can you please submit a minimal console app which demonstrates to inconsistency with? AFAIK the interceptors shouldn't be interfering with AsyncLocal in any way.
(Note that this isn't about thread-local storage, which does not persist across asynchronous operations since those don't necessarily continue on the same thread where they began. This is why AsyncLocal is needed).