23
23
import struct
24
24
import sys
25
25
import time
26
+ import yappi
26
27
from asyncio import AbstractEventLoop , Future , StreamReader
27
28
from typing import (
28
29
TYPE_CHECKING ,
@@ -84,7 +85,7 @@ def __init__(self):
84
85
self ._done = None
85
86
self ._connection_lost = False
86
87
self ._paused = False
87
- self ._drain_waiters = collections . deque ()
88
+ self ._drain_waiter = None
88
89
self ._loop = asyncio .get_running_loop ()
89
90
90
91
def connection_made (self , transport ):
@@ -104,10 +105,11 @@ def get_buffer(self, sizehint: int):
104
105
105
106
def buffer_updated (self , nbytes : int ):
106
107
if nbytes == 0 :
107
- raise OSError ("connection closed" )
108
+ self .connection_lost (OSError ("connection closed" ))
109
+ self ._done .set_result (None )
108
110
self .bytes_read += nbytes
109
111
if self .expecting_header :
110
- self .expected_length , _ , response_to , self .op_code = _UNPACK_HEADER (self ._buffer [:16 ])
112
+ self .expected_length , _ , _ , self .op_code = _UNPACK_HEADER (self ._buffer [:16 ])
111
113
self .expecting_header = False
112
114
113
115
if self .bytes_read == self .expected_length :
@@ -121,34 +123,28 @@ def resume_writing(self):
121
123
assert self ._paused
122
124
self ._paused = False
123
125
124
- for waiter in self ._drain_waiters :
125
- if not waiter .done ():
126
- waiter .set_result (None )
126
+ if self ._drain_waiter and not self ._drain_waiter .done ():
127
+ self ._drain_waiter .set_result (None )
127
128
128
129
def connection_lost (self , exc ):
129
130
self ._connection_lost = True
130
131
# Wake up the writer(s) if currently paused.
131
132
if not self ._paused :
132
133
return
133
134
134
- for waiter in self ._drain_waiters :
135
- if not waiter .done ():
136
- if exc is None :
137
- waiter .set_result (None )
138
- else :
139
- waiter .set_exception (exc )
135
+ if self ._drain_waiter and not self ._drain_waiter .done ():
136
+ if exc is None :
137
+ self ._drain_waiter .set_result (None )
138
+ else :
139
+ self ._drain_waiter .set_exception (exc )
140
140
141
141
async def _drain_helper (self ):
142
142
if self ._connection_lost :
143
143
raise ConnectionResetError ('Connection lost' )
144
144
if not self ._paused :
145
145
return
146
- waiter = self ._loop .create_future ()
147
- self ._drain_waiters .append (waiter )
148
- try :
149
- await waiter
150
- finally :
151
- self ._drain_waiters .remove (waiter )
146
+ self ._drain_waiter = self ._loop .create_future ()
147
+ await self ._drain_waiter
152
148
153
149
def reset (self , buffer : memoryview ):
154
150
self ._buffer = buffer
0 commit comments