debian-forge/osbuild
David Rheinsberg 2bdb287731 sources: make cleanup explicit
This changes the sources module to explicitly cleanup event-loops.
Additionally, the implementation is protected against re-entrency which
we do not support (and do not need).

We did occasionally get the following exception when running
source-servers:

        /usr/lib/python3.8/asyncio/base_events.py:654: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>
          _warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)
        ResourceWarning: Enable tracemalloc to get the object allocation traceback

        Exception ignored in: <function BaseEventLoop.__del__ at 0x7f92589d14c0>
        Traceback (most recent call last):
          File "/usr/lib/python3.8/asyncio/base_events.py", line 656, in __del__
            self.close()
          File "/usr/lib/python3.8/asyncio/unix_events.py", line 58, in close
            super().close()
          File "/usr/lib/python3.8/asyncio/selector_events.py", line 92, in close
            self._close_self_pipe()
          File "/usr/lib/python3.8/asyncio/selector_events.py", line 99, in _close_self_pipe
            self._remove_reader(self._ssock.fileno())
          File "/usr/lib/python3.8/asyncio/selector_events.py", line 274, in _remove_reader
            key = self._selector.get_key(fd)
          File "/usr/lib/python3.8/selectors.py", line 190, in get_key
            return mapping[fileobj]
          File "/usr/lib/python3.8/selectors.py", line 71, in __getitem__
            fd = self._selector._fileobj_lookup(fileobj)
          File "/usr/lib/python3.8/selectors.py", line 225, in _fileobj_lookup
            return _fileobj_to_fd(fileobj)
          File "/usr/lib/python3.8/selectors.py", line 42, in _fileobj_to_fd
            raise ValueError("Invalid file descriptor: {}".format(fd))
        ValueError: Invalid file descriptor: -1

This is triggered when an event-loop is not closed explicitly via
`event_loop.close()`. It then tries to cleanup explicitly. The problem
here is that python has no knowledge of in which order it should
collect GC'ed objects. This might end up more or less random. Therefore,
file-descriptors might be closed in arbitrary order, leading to the
event-loop being unable to unregister its internal objects.

I am not entirely sure whether this is the case here. However, the error
definitely triggers on the internal event-loop socketpair, which there
is no other external access to. Furthermore, this socketpair is only set
to -1 in its own __del__ function. So unless we have a memory
corruption, I see nothing else that could trigger this.

With this fix in place, I can run `test_sources.py` in a loop without
triggering the bug.

It is quite likely that our other `*Server` classes need the same fix. I
did not verify, yet.
2020-04-24 11:48:16 +02:00
..
util util: mark as module 2020-04-21 17:00:04 +02:00
__init__.py pipeline: return logs in --json mode 2019-12-14 13:49:24 +01:00
__main__.py osbuild: add --output-directory=DIR 2020-04-15 15:40:17 +02:00
api.py osbuild: convert to jsoncomm 2020-04-21 13:47:38 +02:00
buildroot.py buildroot: reduce nspawn requirements further 2020-04-22 18:27:10 +02:00
loop.py loop: fix FD leak in mknod() 2020-04-21 13:02:29 +02:00
objectstore.py osbuild: cleanup contextlib usage 2020-04-21 16:02:20 +02:00
pipeline.py osbuild: unify libdir handling 2020-04-21 13:44:43 +02:00
remoteloop.py osbuild: convert to jsoncomm 2020-04-21 13:47:38 +02:00
sources.py sources: make cleanup explicit 2020-04-24 11:48:16 +02:00
tmpfs.py osbuild: split package into separate files 2019-08-21 09:56:50 +04:00
treesum.py treesum: don't use dir_fd parameter in os.scandir() 2019-11-29 00:45:14 +01:00