It looks like instantiated extensions passed to Schema are racy.
Example of racy usage:
strawberry/tests/schema/extensions/test_opentelemetry.py
Lines 200 to 202 in d6137f0
For OpenTelemetryExtension
a single instance of _span_holder
is going to be created and reused.
Beyond just OpenTelemetryExtension
, the setting of execution_context
in ExtensionsRunner
is racy:
strawberry/strawberry/extensions/runner.py
Lines 33 to 40 in d6137f0
You can trivially show this using the following example:
Create app.py
import asyncio
from typing import Optional
import strawberry
from strawberry.extensions import Extension
from strawberry.types.execution import ExecutionContext
class TestExtension(Extension):
def __init__(
self,
*,
execution_context: Optional[ExecutionContext] = None,
):
if execution_context:
self.execution_context = execution_context
def on_request_start(self):
print(f"on_request_start: self={id(self)} execution_context={id(self.execution_context)}")
def on_request_end(self):
print(f"on_request_end: self={id(self)} execution_context={id(self.execution_context)}")
@strawberry.type
class Query:
@strawberry.field
async def test(self, sleep: int) -> int:
await asyncio.sleep(sleep)
return sleep
schema = strawberry.Schema(query=Query, extensions=[TestExtension()])
Then run the following:
strawberry server app --port 3030
In a new window make the following request:
curl 127.0.0.1:3030/graphql -H 'content-type: application/json' --data '{"query": "{ test(sleep: 30) }"}'
And while that request is running, make the concurrent request:
curl 127.0.0.1:3030/graphql -H 'content-type: application/json' --data '{"query": "{ test(sleep: 1) }"}'
If you look at the output of app.py
you'll see the following:
Running strawberry on http://0.0.0.0:3030/graphql π
[2022-08-03 13:04:24]: No operation name
{ test(sleep: 30) }
on_request_start: self=4478445024 execution_context=4478640672
[2022-08-03 13:04:28]: No operation name
{ test(sleep: 1) }
on_request_start: self=4478445024 execution_context=4478932016
on_request_end: self=4478445024 execution_context=4478932016
on_request_end: self=4478445024 execution_context=4478932016
You'll notice there is no on_request_end
for 4478640672
and a double execution of 4478932016
.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too