Skip to content

Commit 7a4f00a

Browse files
committed
Implement Server.start_serving() and related APIs
1 parent b8fb1ef commit 7a4f00a

14 files changed

+231
-86
lines changed

Diff for: tests/test_tcp.py

+69
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ async def start_server():
129129

130130
srv_socks = srv.sockets
131131
self.assertTrue(srv_socks)
132+
if self.has_start_serving():
133+
self.assertTrue(srv.is_serving())
132134

133135
addr = srv_socks[0].getsockname()
134136

@@ -147,6 +149,9 @@ async def start_server():
147149
for srv_sock in srv_socks:
148150
self.assertEqual(srv_sock.fileno(), -1)
149151

152+
if self.has_start_serving():
153+
self.assertFalse(srv.is_serving())
154+
150155
async def start_server_sock():
151156
nonlocal CNT
152157
CNT = 0
@@ -167,6 +172,8 @@ async def start_server_sock():
167172

168173
srv_socks = srv.sockets
169174
self.assertTrue(srv_socks)
175+
if self.has_start_serving():
176+
self.assertTrue(srv.is_serving())
170177

171178
tasks = []
172179
for _ in range(TOTAL_CNT):
@@ -183,6 +190,9 @@ async def start_server_sock():
183190
for srv_sock in srv_socks:
184191
self.assertEqual(srv_sock.fileno(), -1)
185192

193+
if self.has_start_serving():
194+
self.assertFalse(srv.is_serving())
195+
186196
self.loop.run_until_complete(start_server())
187197
self.assertEqual(CNT, TOTAL_CNT)
188198

@@ -206,6 +216,8 @@ async def start_server_ephemeral_ports():
206216

207217
srv_socks = srv.sockets
208218
self.assertTrue(srv_socks)
219+
if self.has_start_serving():
220+
self.assertTrue(srv.is_serving())
209221

210222
host, port = srv_socks[0].getsockname()
211223
self.assertNotEqual(0, port)
@@ -217,6 +229,9 @@ async def start_server_ephemeral_ports():
217229
for srv_sock in srv_socks:
218230
self.assertEqual(srv_sock.fileno(), -1)
219231

232+
if self.has_start_serving():
233+
self.assertFalse(srv.is_serving())
234+
220235
self.loop.run_until_complete(start_server_ephemeral_ports())
221236

222237
def test_create_server_4(self):
@@ -335,6 +350,60 @@ def test_create_server_8(self):
335350
self.loop.create_server(
336351
lambda: None, host='::', port=0, ssl_handshake_timeout=10))
337352

353+
def test_create_server_9(self):
354+
if not self.has_start_serving():
355+
raise unittest.SkipTest()
356+
357+
async def handle_client(reader, writer):
358+
pass
359+
360+
async def start_server():
361+
srv = await asyncio.start_server(
362+
handle_client,
363+
'127.0.0.1', 0,
364+
family=socket.AF_INET,
365+
loop=self.loop,
366+
start_serving=False)
367+
368+
await srv.start_serving()
369+
self.assertTrue(srv.is_serving())
370+
371+
# call start_serving again
372+
await srv.start_serving()
373+
self.assertTrue(srv.is_serving())
374+
375+
srv.close()
376+
await srv.wait_closed()
377+
self.assertFalse(srv.is_serving())
378+
379+
self.loop.run_until_complete(start_server())
380+
381+
def test_create_server_10(self):
382+
if not self.has_start_serving():
383+
raise unittest.SkipTest()
384+
385+
async def handle_client(reader, writer):
386+
pass
387+
388+
async def start_server():
389+
srv = await asyncio.start_server(
390+
handle_client,
391+
'127.0.0.1', 0,
392+
family=socket.AF_INET,
393+
loop=self.loop,
394+
start_serving=False)
395+
396+
fut = asyncio.ensure_future(srv.serve_forever(), loop=self.loop)
397+
await asyncio.sleep(0, loop=self.loop)
398+
self.assertTrue(srv.is_serving())
399+
400+
fut.cancel()
401+
with self.assertRaises(asyncio.CancelledError):
402+
await fut
403+
self.assertFalse(srv.is_serving())
404+
405+
self.loop.run_until_complete(start_server())
406+
338407
def test_create_connection_open_con_addr(self):
339408
async def client(addr):
340409
reader, writer = await asyncio.open_connection(

Diff for: tests/test_unix.py

+10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ async def start_server():
6666
try:
6767
srv_socks = srv.sockets
6868
self.assertTrue(srv_socks)
69+
if self.has_start_serving():
70+
self.assertTrue(srv.is_serving())
6971

7072
tasks = []
7173
for _ in range(TOTAL_CNT):
@@ -83,6 +85,9 @@ async def start_server():
8385
for srv_sock in srv_socks:
8486
self.assertEqual(srv_sock.fileno(), -1)
8587

88+
if self.has_start_serving():
89+
self.assertFalse(srv.is_serving())
90+
8691
# asyncio doesn't cleanup the sock file
8792
self.assertTrue(os.path.exists(sock_name))
8893

@@ -100,6 +105,8 @@ async def start_server_sock(start_server):
100105
try:
101106
srv_socks = srv.sockets
102107
self.assertTrue(srv_socks)
108+
if self.has_start_serving():
109+
self.assertTrue(srv.is_serving())
103110

104111
tasks = []
105112
for _ in range(TOTAL_CNT):
@@ -117,6 +124,9 @@ async def start_server_sock(start_server):
117124
for srv_sock in srv_socks:
118125
self.assertEqual(srv_sock.fileno(), -1)
119126

127+
if self.has_start_serving():
128+
self.assertFalse(srv.is_serving())
129+
120130
# asyncio doesn't cleanup the sock file
121131
self.assertTrue(os.path.exists(sock_name))
122132

Diff for: uvloop/_testbase.py

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def new_loop(self):
6767
def mock_pattern(self, str):
6868
return MockPattern(str)
6969

70+
def has_start_serving(self):
71+
return not (self.is_asyncio_loop() and
72+
sys.version_info[:2] in [(3, 5), (3, 6)])
73+
7074
def is_asyncio_loop(self):
7175
return type(self.loop).__module__.startswith('asyncio.')
7276

Diff for: uvloop/handles/pipe.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ cdef class UnixServer(UVStreamServer):
44

55
@staticmethod
66
cdef UnixServer new(Loop loop, object protocol_factory, Server server,
7+
object backlog,
78
object ssl,
89
object ssl_handshake_timeout,
910
object ssl_shutdown_timeout)

Diff for: uvloop/handles/pipe.pyx

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ cdef class UnixServer(UVStreamServer):
3838

3939
@staticmethod
4040
cdef UnixServer new(Loop loop, object protocol_factory, Server server,
41+
object backlog,
4142
object ssl,
4243
object ssl_handshake_timeout,
4344
object ssl_shutdown_timeout):
4445

4546
cdef UnixServer handle
4647
handle = UnixServer.__new__(UnixServer)
47-
handle._init(loop, protocol_factory, server,
48+
handle._init(loop, protocol_factory, server, backlog,
4849
ssl, ssl_handshake_timeout, ssl_shutdown_timeout)
4950
__pipe_init_uv_handle(<UVStream>handle, loop)
5051
return handle

Diff for: uvloop/handles/streamserver.pxd

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cdef class UVStreamServer(UVSocketHandle):
22
cdef:
3+
int backlog
34
object ssl
45
object ssl_handshake_timeout
56
object ssl_shutdown_timeout
@@ -10,13 +11,15 @@ cdef class UVStreamServer(UVSocketHandle):
1011
# All "inline" methods are final
1112

1213
cdef inline _init(self, Loop loop, object protocol_factory,
13-
Server server, object ssl,
14+
Server server,
15+
object backlog,
16+
object ssl,
1417
object ssl_handshake_timeout,
1518
object ssl_shutdown_timeout)
1619

1720
cdef inline _mark_as_open(self)
1821

19-
cdef inline listen(self, backlog)
22+
cdef inline listen(self)
2023
cdef inline _on_listen(self)
2124

2225
cdef UVStream _make_new_transport(self, object protocol, object waiter)

Diff for: uvloop/handles/streamserver.pyx

+11-8
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@ cdef class UVStreamServer(UVSocketHandle):
1010
self.protocol_factory = None
1111

1212
cdef inline _init(self, Loop loop, object protocol_factory,
13-
Server server, object ssl,
13+
Server server,
14+
object backlog,
15+
object ssl,
1416
object ssl_handshake_timeout,
1517
object ssl_shutdown_timeout):
1618

19+
if not isinstance(backlog, int):
20+
# Don't allow floats
21+
raise TypeError('integer argument expected, got {}'.format(
22+
type(backlog).__name__))
23+
1724
if ssl is not None:
1825
if not isinstance(ssl, ssl_SSLContext):
1926
raise TypeError(
@@ -27,6 +34,7 @@ cdef class UVStreamServer(UVSocketHandle):
2734
raise ValueError(
2835
'ssl_shutdown_timeout is only meaningful with ssl')
2936

37+
self.backlog = backlog
3038
self.ssl = ssl
3139
self.ssl_handshake_timeout = ssl_handshake_timeout
3240
self.ssl_shutdown_timeout = ssl_shutdown_timeout
@@ -35,23 +43,18 @@ cdef class UVStreamServer(UVSocketHandle):
3543
self.protocol_factory = protocol_factory
3644
self._server = server
3745

38-
cdef inline listen(self, backlog):
46+
cdef inline listen(self):
3947
cdef int err
4048
self._ensure_alive()
4149

42-
if not isinstance(backlog, int):
43-
# Don't allow floats
44-
raise TypeError('integer argument expected, got {}'.format(
45-
type(backlog).__name__))
46-
4750
if self.protocol_factory is None:
4851
raise RuntimeError('unable to listen(); no protocol_factory')
4952

5053
if self.opened != 1:
5154
raise RuntimeError('unopened TCPServer')
5255

5356
err = uv.uv_listen(<uv.uv_stream_t*> self._handle,
54-
backlog,
57+
self.backlog,
5558
__uv_streamserver_on_listen)
5659
if err < 0:
5760
exc = convert_error(err)

Diff for: uvloop/handles/tcp.pxd

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ cdef class TCPServer(UVStreamServer):
33

44
@staticmethod
55
cdef TCPServer new(Loop loop, object protocol_factory, Server server,
6-
object ssl, unsigned int flags,
6+
unsigned int flags,
7+
object backlog,
8+
object ssl,
79
object ssl_handshake_timeout,
810
object ssl_shutdown_timeout)
911

Diff for: uvloop/handles/tcp.pyx

+4-2
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ cdef class TCPServer(UVStreamServer):
5757

5858
@staticmethod
5959
cdef TCPServer new(Loop loop, object protocol_factory, Server server,
60-
object ssl, unsigned int flags,
60+
unsigned int flags,
61+
object backlog,
62+
object ssl,
6163
object ssl_handshake_timeout,
6264
object ssl_shutdown_timeout):
6365

6466
cdef TCPServer handle
6567
handle = TCPServer.__new__(TCPServer)
66-
handle._init(loop, protocol_factory, server,
68+
handle._init(loop, protocol_factory, server, backlog,
6769
ssl, ssl_handshake_timeout, ssl_shutdown_timeout)
6870
__tcp_init_uv_handle(<UVStream>handle, loop, flags)
6971
return handle

Diff for: uvloop/includes/stdlib.pxi

+3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ cdef gc_disable = gc.disable
6666
cdef iter_chain = itertools.chain
6767
cdef inspect_isgenerator = inspect.isgenerator
6868

69+
cdef int has_IPV6_V6ONLY = hasattr(socket, 'IPV6_V6ONLY')
70+
cdef int IPV6_V6ONLY = getattr(socket, 'IPV6_V6ONLY', -1)
6971
cdef int has_SO_REUSEPORT = hasattr(socket, 'SO_REUSEPORT')
7072
cdef int SO_REUSEPORT = getattr(socket, 'SO_REUSEPORT', 0)
7173
cdef int SO_BROADCAST = getattr(socket, 'SO_BROADCAST')
@@ -118,6 +120,7 @@ cdef sys_set_coroutine_wrapper = sys.set_coroutine_wrapper
118120
cdef sys_get_coroutine_wrapper = sys.get_coroutine_wrapper
119121
cdef sys_getframe = sys._getframe
120122
cdef sys_version_info = sys.version_info
123+
cdef str sys_platform = sys.platform
121124

122125
cdef ssl_SSLContext = ssl.SSLContext
123126
cdef ssl_MemoryBIO = ssl.MemoryBIO

Diff for: uvloop/loop.pxd

-9
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,6 @@ cdef class Loop:
161161

162162
cdef _getnameinfo(self, system.sockaddr *addr, int flags)
163163

164-
cdef _create_server(self, system.sockaddr *addr,
165-
object protocol_factory,
166-
Server server,
167-
object ssl,
168-
bint reuse_port,
169-
object backlog,
170-
object ssl_handshake_timeout,
171-
object ssl_shutdown_timeout)
172-
173164
cdef _track_transport(self, UVBaseTransport transport)
174165
cdef _fileobj_to_fd(self, fileobj)
175166
cdef _ensure_fd_no_transport(self, fd)

0 commit comments

Comments
 (0)