-
-
Notifications
You must be signed in to change notification settings - Fork 748
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
ContextVars pollution when uvicorn installed without [standard] extensions #2167
Comments
This seems to be the same issue as in #2152 |
I've confirmed it also fails with Python 3.12, and it doesn't reproduce with Hypercorn. It only reproduces with @graingert Do you know whose's fault is it here? |
@Kludex And I reproduce this on
env
import time
import requests
print("")
print("Starting...")
def main(payload_len):
# Everything is good when payload is small
huge_payload = "a" * payload_len
# Send request each 1 second reusing single connection (without connection reuse it works well)
with requests.Session() as session:
# while True:
for i in range(2):
try:
response = session.post('http://127.0.0.1:8002/test', huge_payload)
print(f"payload_len:{payload_len}", response.text) # server will be responding with either 'OK' or 'FAIL'
# In case if server reports 'FAIL' - we reproduced the issue and are OK to exit
if response.text == "FAIL":
break
except KeyboardInterrupt:
break
except BaseException as ex:
print(str(ex))
time.sleep(0.1)
if __name__ == "__main__":
payload_len = 65531
for n in range(payload_len, payload_len + 10):
main(n) why 65536(64KB)?I grep 65536 in uvicorn code, found that: # uvicorn/protocols/http/flow_control.py
# Line 15
HIGH_WATER_LIMIT = 65536
# uvicorn/protocols/http/h11_impl.py
# Line 280
def handle_events(self) -> None:
elif event_type is h11.Data:
if self.conn.our_state is h11.DONE:
continue
print(f"{id(self)=} {len(event.data)=}")
self.cycle.body += event.data
if len(self.cycle.body) > HIGH_WATER_LIMIT:
self.flow.pause_reading()
self.cycle.message_event.set() What happens in
|
@graingert Do you know whose's fault is it here? |
I confirm the behavior in a Mac m1 pro. server output
client output
|
Discussed in #2044
Originally posted by vladyslav-burylov July 12, 2023
Hi team, we have discovered a weird ContextVars behaviour when uvicorn being installed without [standard] extensions.
Can you please take a look - should this be considered as a bug or maybe you can help to explain why it happens?
Summary
Workarounds
uvicorn[standard]
instead of plainuvicorn
(seems to be a good option)scope
to store request-bound data (not always possible: for example opentelemetry cloud tracing middleware stores current trace span inside context var and this logic cannot be changed)Steps to reproduce
Hardware/OS/tools
Prepare environment
Prepare test scripts - create following files:
client.py
server.py
Executing test
Expected behaviour
Actual behaviour
Notes
uvicorn[standard]
- maybe it's happening because standard edition utilisesuvloop
?Important
The text was updated successfully, but these errors were encountered: