File tree Expand file tree Collapse file tree 2 files changed +15
-11
lines changed Expand file tree Collapse file tree 2 files changed +15
-11
lines changed Original file line number Diff line number Diff line change @@ -318,14 +318,7 @@ async def leave(self):
318
318
# {'type': 'http.request', 'body': b'', 'more_body': True}
319
319
# {'type': 'http.request', 'body': b'', 'more_body': False}
320
320
# {'type': 'http.disconnect'}
321
- while True :
322
- event = await self .receive ()
323
- if event is None :
324
- break
325
- if event .get ('type' ) == 'http.disconnect' :
326
- break
327
- if event .get ('type' ) == 'http.request' and event .get ('more_body' , False ) is False :
328
- break
321
+ await self .receive .block_until_http_input_closed ()
329
322
# finally, we close our side
330
323
# it is important to do it, after the other side has closed his side,
331
324
# because some asgi servers (like hypercorn) will remove the stream
Original file line number Diff line number Diff line change @@ -98,14 +98,19 @@ class ReceiveChannel:
98
98
99
99
def __init__ (self , receive : Receive ) -> None :
100
100
self ._queue = asyncio .Queue [Union [ASGIReceiveEvent , RestateEvent ]]()
101
+ self ._http_input_closed = asyncio .Event ()
102
+ self ._disconnected = asyncio .Event ()
101
103
102
104
async def loop ():
103
105
"""Receive loop."""
104
- while True :
106
+ while not self . _disconnected . is_set () :
105
107
event = await receive ()
108
+ if event .get ('type' ) == 'http.request' and not event .get ('more_body' , False ):
109
+ self ._http_input_closed .set ()
110
+ elif event .get ('type' ) == 'http.disconnect' :
111
+ self ._http_input_closed .set ()
112
+ self ._disconnected .set ()
106
113
await self ._queue .put (event )
107
- if event .get ('type' ) == 'http.disconnect' :
108
- break
109
114
110
115
self ._task = asyncio .create_task (loop ())
111
116
@@ -115,12 +120,18 @@ async def __call__(self) -> ASGIReceiveEvent | RestateEvent:
115
120
self ._queue .task_done ()
116
121
return what
117
122
123
+ async def block_until_http_input_closed (self ) -> None :
124
+ """Wait until the HTTP input is closed"""
125
+ await self ._http_input_closed .wait ()
126
+
118
127
async def enqueue_restate_event (self , what : RestateEvent ):
119
128
"""Add a message."""
120
129
await self ._queue .put (what )
121
130
122
131
async def close (self ):
123
132
"""Close the channel."""
133
+ self ._http_input_closed .set ()
134
+ self ._disconnected .set ()
124
135
if self ._task .done ():
125
136
return
126
137
self ._task .cancel ()
You can’t perform that action at this time.
0 commit comments