Skip to content

Event loop needs to have deterministic release of resources #264

Open
@jamessan

Description

@jamessan

Running the tests with Python 3.5.3, this traceback is dumped to the console:

$ nosetests3
...................................................
----------------------------------------------------------------------
Ran 51 tests in 1.613s

OK
Exception ignored in: <bound method BaseEventLoop.__del__ of <_UnixSelectorEventLoop running=False closed=True debug=False>>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/base_events.py", line 511, in __del__
  File "/usr/lib/python3.5/asyncio/unix_events.py", line 65, in close
  File "/usr/lib/python3.5/asyncio/unix_events.py", line 146, in remove_signal_handler
  File "/usr/lib/python3.5/signal.py", line 47, in signal
TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object

This appears to be due to nothing explicitly close()ing the asyncio event loop. There's discussion about this in Python issue 23548. As Guido mentions, the automatic tear down of resources is only partially ordered, so we can't rely on that to properly clean up.

Enabling asyncio's suggested debugging knobs also indicates that we're not closing all of the subprocess transport handles (likely similar for the other transports, too):

/usr/lib/python3.5/asyncio/base_subprocess.py:130: ResourceWarning: unclosed transport <_UnixSubprocessTransport pid=4782 running stdin=<_UnixWritePipeTransport fd=8 idle bufsize=0> stdout=<_UnixReadPipeTransport fd=9 polling> stderr=<_UnixReadPipeTransport fd=11 polling>>
sys:1: ResourceWarning: unclosed file <_io.FileIO name=9 mode='rb' closefd=True>
sys:1: ResourceWarning: unclosed file <_io.FileIO name=11 mode='rb' closefd=True>
/usr/lib/python3.5/asyncio/base_events.py:509: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=True>
Exception ignored in: <bound method BaseEventLoop.__del__ of <_UnixSelectorEventLoop running=False closed=True debug=True>>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/base_events.py", line 511, in __del__
  File "/usr/lib/python3.5/asyncio/unix_events.py", line 65, in close
  File "/usr/lib/python3.5/asyncio/unix_events.py", line 146, in remove_signal_handler
  File "/usr/lib/python3.5/signal.py", line 47, in signal
TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object
sys:1: ResourceWarning: unclosed file <_io.FileIO name=8 mode='wb' closefd=True>
/usr/lib/python3.5/asyncio/unix_events.py:422: ResourceWarning: unclosed transport <_UnixReadPipeTransport closing fd=9 open>
/usr/lib/python3.5/asyncio/unix_events.py:422: ResourceWarning: unclosed transport <_UnixReadPipeTransport closing fd=11 open>
/usr/lib/python3.5/asyncio/unix_events.py:622: ResourceWarning: unclosed transport <_UnixWritePipeTransport closing fd=8 open>

Diff to enable debugging knobs:

diff --git a/neovim/msgpack_rpc/event_loop/asyncio.py b/neovim/msgpack_rpc/event_loop/asyncio.py
index b2ea77b..6e0edca 100644
--- a/neovim/msgpack_rpc/event_loop/asyncio.py
+++ b/neovim/msgpack_rpc/event_loop/asyncio.py
@@ -23,6 +23,8 @@ except (ImportError, SyntaxError):
 
 from .base import BaseEventLoop
 
+import warnings
+warnings.simplefilter('default')
 
 loop_cls = asyncio.SelectorEventLoop
 if os.name == 'nt':
@@ -72,6 +74,7 @@ class AsyncioEventLoop(BaseEventLoop, asyncio.Protocol,
 
     def _init(self):
         self._loop = loop_cls()
+        self._loop.set_debug(True)
         self._queued_data = deque()
         self._fact = lambda: self
 

Cc @mhinz

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions