Commit 134f26bf authored by Jason Madden's avatar Jason Madden

Make the BackdoorServer kill its spawned greenlets when it is stopped.

Hopefully this will help diagnose the timeout error seen (only) on
Appveyor: The test that runs after test_multi hangs; all the other tests
work. (This was verified by changing the name of test_multi and thus its
sort order; the test after it is the one that fails.)
parent e6a45fb4
......@@ -141,8 +141,11 @@ Other Changes
each other. **Note:** Writing to the *io* property of a FileObject should be
considered deprecated.
- Timeout exceptions (and other asynchronous exceptions) could cause
the Backdoor server to fail to properly manage the
stdout/stderr/stdin values. Reported with a patch in :pr:`874` by stefanmh.
the BackdoorServer to fail to properly manage the
stdout/stderr/stdin values. Reported with a patch in :pr:`874` by
stefanmh.
- The BackDoorServer now tracks spawned greenlets (connections) and
kills them in its ``stop`` method.
Servers
~~~~~~~
......
......@@ -16,6 +16,7 @@ from code import InteractiveConsole
from gevent.greenlet import Greenlet
from gevent.hub import getcurrent
from gevent.server import StreamServer
from gevent.pool import Pool
__all__ = ['BackdoorServer']
......@@ -88,6 +89,10 @@ class BackdoorServer(StreamServer):
Hello from gevent backdoor!
>> print(foo)
From defined scope!
.. versionchanged:: 1.2a1
Spawned greenlets are now tracked in a pool and killed when the server
is stopped.
"""
def __init__(self, listener, locals=None, banner=None, **server_args):
......@@ -96,7 +101,8 @@ class BackdoorServer(StreamServer):
at the top-level.
:keyword banner: If geven, a string that will be printed to each connecting user.
"""
StreamServer.__init__(self, listener, spawn=_Greenlet_stdreplace.spawn, **server_args)
group = Pool(greenlet_class=_Greenlet_stdreplace) # no limit on number
StreamServer.__init__(self, listener, spawn=group, **server_args)
_locals = {'__doc__': None, '__name__': '__console__'}
if locals:
_locals.update(locals)
......
from __future__ import print_function
import greentest
import gevent
from gevent import socket
from gevent import backdoor
from _six import xrange
def read_until(conn, postfix):
read = b''
......@@ -30,6 +29,7 @@ class Test(greentest.TestCase):
def tearDown(self):
self._server.stop()
self._server = None
gevent.sleep() # let spawned greenlets die
super(Test, self).tearDown()
def _make_server(self, *args, **kwargs):
......@@ -48,25 +48,29 @@ class Test(greentest.TestCase):
line = readline(conn)
self.assertEqual(line, '')
conn.close()
self.close_on_teardown.remove(conn)
def test_multi(self):
self._make_server()
def connect():
conn = self._create_connection()
read_until(conn, '>>> ')
read_until(conn, b'>>> ')
conn.sendall(b'2+2\r\n')
line = readline(conn)
self.assertEqual(line.strip(), '4', repr(line))
self._close(conn)
jobs = [gevent.spawn(connect) for _ in xrange(10)]
gevent.joinall(jobs, raise_error=True)
jobs = [gevent.spawn(connect) for _ in range(10)]
done = gevent.joinall(jobs, raise_error=True)
self.assertEqual(len(done), len(jobs), done)
def test_quit(self):
self._make_server()
conn = self._create_connection()
read_until(conn, '>>> ')
read_until(conn, b'>>> ')
self._close(conn)
def test_sys_exit(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment