-
Notifications
You must be signed in to change notification settings - Fork 227
Allow config for switching between thread locals and contextvars for execution_context #451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@ramshaw888 thanks for the excellent write up! I think introducing a setting for this makes a lot of sense, with the dotted import path of the execution context class, similar to what we do with the transport class: apm-agent-python/elasticapm/conf/__init__.py Line 238 in a9d565b
apm-agent-python/elasticapm/base.py Line 124 in a9d565b
What complicates this a bit is that configuration is bound to the agent instance, while this is setting should apply process-wide. This isn't the first time something like process-wide settings come up (e.g. we'd would like to make it possible to configure auto-instrumentation via setting), so it's probably a good time to come up with a strategy for it. |
@beniwohli I wonder if the (emergency) solution proposed by @ramshaw888 should be configurable. In this case the reason for using Also, just a complementary note to @ramshaw888's excellent summary: |
On second thoughts I do agree with @bhodorog's suggestion to enforce (or at least default to) using I originally suggested the optional config approach because it's more generic and would be helpful in other use cases other this. The 2 possible ways I see this could be achieved are:
Without knowing the codebase super well yet, I strongly lean towards the latter option. Splitting the config sounds dirty, and I don't really see a strong reason why the execution_context can't be tied to the agent. |
@ramshaw888 I don't think attaching execution context to the agent instance is an option with the current API. Thinks like At some point we might need to redesign those APIs that currently work without an agent instance to require one, but that is a larger piece of work. I like your solution in #453 as a "quick fix" to get gevent back to working (more or less). |
Uh oh!
There was an error while loading. Please reload this page.
Is your feature request related to a problem? Please describe.
I'm trying to get some preliminary support working for apps that use
gevent
.In Python<3.7 the agent uses thread locals to back the
execution_context
object, while in Python>=3.7 it uses context vars. The functionality to switch between the two was introduced in #291 which was 'a partial "import" of the asyncio work done in #252"'.I've had some success in using the agent with Python<3.7 project because
gevent
monkey patches thread locals to be "greenlet-safe" (see here). In >=3.7 however the agent defaults to using contextvars which are not monkey patched by gevent, resulting in race conditions where multiple flask request transactions share the same contextvars.Describe the solution you'd like
My proposed solution is to have an optional config value which determines whether to use thread locals, or contextvars as the "backing" for the
execution_context
object. If the config value is not present, then it should fall back to the existing logic.Describe alternatives you've considered
Another option is to check whether or not thread locals has been monkey patched by gevent, and then assuming use of thread locals instead of contextvars. I understand that elastic has not fully committed to gevent support which is why I think an optional config might be a better solution to begin with.
Additional context
Additionally, as suggested by @bhodorog (#16 (comment)) this would pave the way for alternative "thread" storage options like werkzeug locals.
The text was updated successfully, but these errors were encountered: