Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #90 from blodow/feat/add_send_timeout
[#89] Add SSE Send Timeout
- Loading branch information
Showing
6 changed files
with
380 additions
and
365 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import sys | ||
from contextlib import contextmanager | ||
from typing import Generator | ||
|
||
# AnyIO v4 introduces a breaking change that groups all exceptions in a task | ||
# group into an exception group. | ||
# This file allows to be compatible with AnyIO <4 and >=4 by unwrapping groups | ||
# if they only contain a single exception. It also supports python <3.11 (before | ||
# exception groups support) and >=3.11. | ||
# Solution as proposed in https://anyio.readthedocs.io/en/stable/migration.html | ||
|
||
has_exceptiongroups = True | ||
if sys.version_info < (3, 11): | ||
try: | ||
from exceptiongroup import BaseExceptionGroup | ||
except ImportError: | ||
has_exceptiongroups = False | ||
|
||
|
||
@contextmanager | ||
def collapse_excgroups() -> Generator[None, None, None]: | ||
try: | ||
yield | ||
except BaseException as exc: | ||
if has_exceptiongroups: | ||
while isinstance(exc, BaseExceptionGroup) and len(exc.exceptions) == 1: | ||
exc = exc.exceptions[0] | ||
|
||
raise exc | ||
|
||
|
||
__all__ = ["collapse_excgroups"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
""" | ||
https://github.com/sysid/sse-starlette/issues/89 | ||
Server Simulation: | ||
Run with: uvicorn tests.integration.frozen_client:app | ||
Client Simulation: | ||
% curl -s -N localhost:8000/events > /dev/null | ||
^Z (suspend process -> no consumption of messages but connection alive) | ||
Measure resource consumption: | ||
connections: lsof -i :8000 | ||
buffers: netstat -m | ||
""" | ||
import anyio | ||
from starlette.applications import Starlette | ||
from starlette.routing import Route | ||
|
||
from sse_starlette import EventSourceResponse | ||
import uvicorn | ||
|
||
|
||
async def events(request): | ||
async def _event_generator(): | ||
try: | ||
i = 0 | ||
while True: | ||
i += 1 | ||
if i % 100 == 0: | ||
print(i) | ||
yield dict(data={i: " " * 4096}) | ||
await anyio.sleep(0.001) | ||
finally: | ||
print("disconnected") | ||
return EventSourceResponse(_event_generator(), send_timeout=10) | ||
|
||
app = Starlette( | ||
debug=True, | ||
routes=[ | ||
Route("/events", events), | ||
], | ||
) | ||
|
||
if __name__ == "__main__": | ||
uvicorn.run(app, host="0.0.0.0", port=8000, log_level="trace", log_config=None) # type: ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters