Skip to content

Commit 26f36ac

Browse files
committed
CRF: extract add_water_defaults()
* Also fixed bug that set_write_buffer_limits(low=16385) fails
1 parent f375819 commit 26f36ac

File tree

7 files changed

+73
-47
lines changed

7 files changed

+73
-47
lines changed

tests/test_tcp.py

+40
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,46 @@ def test_create_server_stream_bittype(self):
11491149
srv.close()
11501150
self.loop.run_until_complete(srv.wait_closed())
11511151

1152+
def test_flowcontrol_mixin_set_write_limits(self):
1153+
async def client(addr):
1154+
paused = False
1155+
1156+
class Protocol(asyncio.Protocol):
1157+
def pause_writing(self):
1158+
nonlocal paused
1159+
paused = True
1160+
1161+
def resume_writing(self):
1162+
nonlocal paused
1163+
paused = False
1164+
1165+
t, p = await self.loop.create_connection(Protocol, *addr)
1166+
1167+
t.write(b'q' * 512)
1168+
self.assertEqual(t.get_write_buffer_size(), 512)
1169+
1170+
t.set_write_buffer_limits(low=16385)
1171+
self.assertFalse(paused)
1172+
self.assertEqual(t.get_write_buffer_limits(), (16385, 65540))
1173+
1174+
with self.assertRaisesRegex(ValueError, 'high.*must be >= low'):
1175+
t.set_write_buffer_limits(high=0, low=1)
1176+
1177+
t.set_write_buffer_limits(high=1024, low=128)
1178+
self.assertFalse(paused)
1179+
self.assertEqual(t.get_write_buffer_limits(), (128, 1024))
1180+
1181+
t.set_write_buffer_limits(high=256, low=128)
1182+
self.assertTrue(paused)
1183+
self.assertEqual(t.get_write_buffer_limits(), (128, 256))
1184+
1185+
t.close()
1186+
1187+
with self.tcp_server(lambda sock: sock.recv_all(1),
1188+
max_clients=1,
1189+
backlog=1) as srv:
1190+
self.loop.run_until_complete(client(srv.addr))
1191+
11521192

11531193
class Test_AIO_TCP(_TestTCP, tb.AIOTestCase):
11541194
pass

uvloop/handles/basetransport.pxd

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ cdef class UVBaseTransport(UVSocketHandle):
2121

2222
# All "inline" methods are final
2323

24-
cdef inline _set_write_buffer_limits(self, int high=*, int low=*)
2524
cdef inline _maybe_pause_protocol(self)
2625
cdef inline _maybe_resume_protocol(self)
2726

uvloop/handles/basetransport.pyx

+5-26
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ cdef class UVBaseTransport(UVSocketHandle):
22

33
def __cinit__(self):
44
# Flow control
5-
self._high_water = FLOW_CONTROL_HIGH_WATER
6-
self._low_water = FLOW_CONTROL_LOW_WATER
5+
self._high_water = FLOW_CONTROL_HIGH_WATER * 1024
6+
self._low_water = FLOW_CONTROL_HIGH_WATER // 4
77

88
self._protocol = None
99
self._protocol_connected = 0
@@ -59,25 +59,6 @@ cdef class UVBaseTransport(UVSocketHandle):
5959
'protocol': self._protocol,
6060
})
6161

62-
cdef inline _set_write_buffer_limits(self, int high=-1, int low=-1):
63-
if high == -1:
64-
if low == -1:
65-
high = FLOW_CONTROL_HIGH_WATER
66-
else:
67-
high = FLOW_CONTROL_LOW_WATER
68-
69-
if low == -1:
70-
low = high // 4
71-
72-
if not high >= low >= 0:
73-
raise ValueError('high (%r) must be >= low (%r) must be >= 0' %
74-
(high, low))
75-
76-
self._high_water = high
77-
self._low_water = low
78-
79-
self._maybe_pause_protocol()
80-
8162
cdef inline _maybe_pause_protocol(self):
8263
cdef:
8364
size_t size = self._get_write_buffer_size()
@@ -283,12 +264,10 @@ cdef class UVBaseTransport(UVSocketHandle):
283264
def set_write_buffer_limits(self, high=None, low=None):
284265
self._ensure_alive()
285266

286-
if high is None:
287-
high = -1
288-
if low is None:
289-
low = -1
267+
self._high_water, self._low_water = add_water_defaults(
268+
high, low, FLOW_CONTROL_HIGH_WATER)
290269

291-
self._set_write_buffer_limits(high, low)
270+
self._maybe_pause_protocol()
292271

293272
def get_write_buffer_limits(self):
294273
return (self._low_water, self._high_water)

uvloop/includes/consts.pxi

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
DEF UV_STREAM_RECV_BUF_SIZE = 256000 # 250kb
22

3-
DEF FLOW_CONTROL_HIGH_WATER = 65536
4-
DEF FLOW_CONTROL_LOW_WATER = 16384
3+
DEF FLOW_CONTROL_HIGH_WATER = 64 # KiB
4+
DEF FLOW_CONTROL_HIGH_WATER_SSL_READ = 256 # KiB
5+
DEF FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512 # KiB
56

67
DEF DEFAULT_FREELIST_SIZE = 250
78

uvloop/includes/flowcontrol.pxd

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cdef inline add_water_defaults(high, low, int kb):
2+
cdef int h, l
3+
if high is None:
4+
if low is None:
5+
h = kb * 1024
6+
else:
7+
l = low
8+
h = 4 * l
9+
else:
10+
h = high
11+
if low is None:
12+
l = h // 4
13+
else:
14+
l = low
15+
16+
if not h >= l >= 0:
17+
raise ValueError('high (%r) must be >= low (%r) must be >= 0' %
18+
(h, l))
19+
20+
return h, l

uvloop/loop.pyx

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ from .includes.python cimport PY_VERSION_HEX, \
2121
PyContext_Exit, \
2222
PyMemoryView_FromMemory, PyBUF_WRITE, \
2323
PyMemoryView_FromObject, PyMemoryView_Check
24+
from .includes.flowcontrol cimport add_water_defaults
2425

2526
from libc.stdint cimport uint64_t
2627
from libc.string cimport memset, strerror, memcpy

uvloop/sslproto.pyx

+4-18
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,8 @@ cdef class SSLProtocol:
766766
return self._outgoing.pending + self._write_buffer_size
767767

768768
cdef _set_write_buffer_limits(self, high=None, low=None):
769-
high, low = _add_water_defaults(high, low, 512)
769+
high, low = add_water_defaults(high, low,
770+
FLOW_CONTROL_HIGH_WATER_SSL_WRITE)
770771
self._outgoing_high_water = high
771772
self._outgoing_low_water = low
772773

@@ -800,7 +801,8 @@ cdef class SSLProtocol:
800801
self._transport.resume_reading()
801802

802803
cdef _set_read_buffer_limits(self, high=None, low=None):
803-
high, low = _add_water_defaults(high, low, 256)
804+
high, low = add_water_defaults(high, low,
805+
FLOW_CONTROL_HIGH_WATER_SSL_READ)
804806
self._incoming_high_water = high
805807
self._incoming_low_water = low
806808

@@ -840,19 +842,3 @@ cdef class SSLProtocol:
840842
'transport': self._transport,
841843
'protocol': self,
842844
})
843-
844-
845-
cdef _add_water_defaults(high, low, kb):
846-
if high is None:
847-
if low is None:
848-
high = kb * 1024
849-
else:
850-
high = 4 * low
851-
if low is None:
852-
low = high // 4
853-
854-
if not high >= low >= 0:
855-
raise ValueError(
856-
f'high ({high!r}) must be >= low ({low!r}) must be >= 0')
857-
858-
return high, low

0 commit comments

Comments
 (0)