18
18
import asyncio
19
19
import errno
20
20
import socket
21
+ import statistics
21
22
import struct
22
23
import sys
23
24
import time
68
69
# Errors raised by sockets (and TLS sockets) when in non-blocking mode.
69
70
BLOCKING_IO_ERRORS = (BlockingIOError , BLOCKING_IO_LOOKUP_ERROR , * ssl_support .BLOCKING_IO_ERRORS )
70
71
72
+
71
73
async def async_sendall_stream (stream : asyncio .StreamWriter , buf : bytes ) -> None :
72
74
try :
73
75
stream .write (buf )
@@ -77,161 +79,14 @@ async def async_sendall_stream(stream: asyncio.StreamWriter, buf: bytes) -> None
77
79
raise socket .timeout ("timed out" ) from exc
78
80
79
81
80
- if sys .platform != "win32" :
81
-
82
- async def _async_sendall_ssl (
83
- sock : Union [socket .socket , _sslConn ], buf : bytes , loop : AbstractEventLoop
84
- ) -> None :
85
- view = memoryview (buf )
86
- sent = 0
87
-
88
- def _is_ready (fut : Future ) -> None :
89
- if fut .done ():
90
- return
91
- fut .set_result (None )
92
-
93
- while sent < len (buf ):
94
- try :
95
- sent += sock .send (view [sent :])
96
- except BLOCKING_IO_ERRORS as exc :
97
- fd = sock .fileno ()
98
- # Check for closed socket.
99
- if fd == - 1 :
100
- raise SSLError ("Underlying socket has been closed" ) from None
101
- if isinstance (exc , BLOCKING_IO_READ_ERROR ):
102
- fut = loop .create_future ()
103
- loop .add_reader (fd , _is_ready , fut )
104
- try :
105
- await fut
106
- finally :
107
- loop .remove_reader (fd )
108
- if isinstance (exc , BLOCKING_IO_WRITE_ERROR ):
109
- fut = loop .create_future ()
110
- loop .add_writer (fd , _is_ready , fut )
111
- try :
112
- await fut
113
- finally :
114
- loop .remove_writer (fd )
115
- if _HAVE_PYOPENSSL and isinstance (exc , BLOCKING_IO_LOOKUP_ERROR ):
116
- fut = loop .create_future ()
117
- loop .add_reader (fd , _is_ready , fut )
118
- try :
119
- loop .add_writer (fd , _is_ready , fut )
120
- await fut
121
- finally :
122
- loop .remove_reader (fd )
123
- loop .remove_writer (fd )
124
-
125
- async def _async_receive_ssl (
126
- conn : _sslConn , length : int , loop : AbstractEventLoop , once : Optional [bool ] = False
127
- ) -> memoryview :
128
- mv = memoryview (bytearray (length ))
129
- total_read = 0
130
-
131
- def _is_ready (fut : Future ) -> None :
132
- if fut .done ():
133
- return
134
- fut .set_result (None )
135
-
136
- while total_read < length :
137
- try :
138
- read = conn .recv_into (mv [total_read :])
139
- if read == 0 :
140
- raise OSError ("connection closed" )
141
- # KMS responses update their expected size after the first batch, stop reading after one loop
142
- if once :
143
- return mv [:read ]
144
- total_read += read
145
- except BLOCKING_IO_ERRORS as exc :
146
- fd = conn .fileno ()
147
- # Check for closed socket.
148
- if fd == - 1 :
149
- raise SSLError ("Underlying socket has been closed" ) from None
150
- if isinstance (exc , BLOCKING_IO_READ_ERROR ):
151
- fut = loop .create_future ()
152
- loop .add_reader (fd , _is_ready , fut )
153
- try :
154
- await fut
155
- finally :
156
- loop .remove_reader (fd )
157
- if isinstance (exc , BLOCKING_IO_WRITE_ERROR ):
158
- fut = loop .create_future ()
159
- loop .add_writer (fd , _is_ready , fut )
160
- try :
161
- await fut
162
- finally :
163
- loop .remove_writer (fd )
164
- if _HAVE_PYOPENSSL and isinstance (exc , BLOCKING_IO_LOOKUP_ERROR ):
165
- fut = loop .create_future ()
166
- loop .add_reader (fd , _is_ready , fut )
167
- try :
168
- loop .add_writer (fd , _is_ready , fut )
169
- await fut
170
- finally :
171
- loop .remove_reader (fd )
172
- loop .remove_writer (fd )
173
- return mv
174
-
175
- else :
176
- # The default Windows asyncio event loop does not support loop.add_reader/add_writer:
177
- # https://docs.python.org/3/library/asyncio-platforms.html#asyncio-platform-support
178
- # Note: In PYTHON-4493 we plan to replace this code with asyncio streams.
179
- async def _async_sendall_ssl (
180
- sock : Union [socket .socket , _sslConn ], buf : bytes , dummy : AbstractEventLoop
181
- ) -> None :
182
- view = memoryview (buf )
183
- total_length = len (buf )
184
- total_sent = 0
185
- # Backoff starts at 1ms, doubles on timeout up to 512ms, and halves on success
186
- # down to 1ms.
187
- backoff = 0.001
188
- while total_sent < total_length :
189
- try :
190
- sent = sock .send (view [total_sent :])
191
- except BLOCKING_IO_ERRORS :
192
- await asyncio .sleep (backoff )
193
- sent = 0
194
- if sent > 0 :
195
- backoff = max (backoff / 2 , 0.001 )
196
- else :
197
- backoff = min (backoff * 2 , 0.512 )
198
- total_sent += sent
199
-
200
- async def _async_receive_ssl (
201
- conn : _sslConn , length : int , dummy : AbstractEventLoop , once : Optional [bool ] = False
202
- ) -> memoryview :
203
- mv = memoryview (bytearray (length ))
204
- total_read = 0
205
- # Backoff starts at 1ms, doubles on timeout up to 512ms, and halves on success
206
- # down to 1ms.
207
- backoff = 0.001
208
- while total_read < length :
209
- try :
210
- read = conn .recv_into (mv [total_read :])
211
- if read == 0 :
212
- raise OSError ("connection closed" )
213
- # KMS responses update their expected size after the first batch, stop reading after one loop
214
- if once :
215
- return mv [:read ]
216
- except BLOCKING_IO_ERRORS :
217
- await asyncio .sleep (backoff )
218
- read = 0
219
- if read > 0 :
220
- backoff = max (backoff / 2 , 0.001 )
221
- else :
222
- backoff = min (backoff * 2 , 0.512 )
223
- total_read += read
224
- return mv
225
-
226
-
227
82
def sendall (sock : Union [socket .socket , _sslConn ], buf : bytes ) -> None :
228
83
sock .sendall (buf )
229
84
230
85
231
86
async def _poll_cancellation (conn : AsyncConnection ) -> None :
232
- # while True:
233
- # if conn.cancel_context.cancelled:
234
- # return
87
+ while True :
88
+ if conn .cancel_context .cancelled :
89
+ return
235
90
236
91
await asyncio .sleep (_POLL_TIMEOUT )
237
92
@@ -295,19 +150,11 @@ async def async_receive_data_socket(
295
150
sock .settimeout (sock_timeout )
296
151
297
152
298
-
299
153
async def _async_receive_stream (reader : asyncio .StreamReader , length : int ) -> memoryview :
300
- mv = bytearray (length )
301
- total_read = 0
302
-
303
- while total_read < length :
304
- bytes = await reader .read (length )
305
- chunk_length = len (bytes )
306
- if chunk_length == 0 :
307
- raise OSError ("connection closed" )
308
- mv [total_read :] = bytes
309
- total_read += chunk_length
310
- return memoryview (mv )
154
+ try :
155
+ return memoryview (await reader .readexactly (length ))
156
+ except asyncio .IncompleteReadError :
157
+ raise OSError ("connection closed" )
311
158
312
159
def receive_data (conn : Connection , length : int , deadline : Optional [float ]) -> memoryview :
313
160
buf = bytearray (length )
0 commit comments