From ad505ee8e796f44b96dd8486bd3f1689a9c6e7a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= <sybren@stuvel.eu>
Date: Thu, 26 Jan 2017 10:23:37 +0100
Subject: [PATCH] Worker: patching asyncio to avoid an occasional crash

Thanks to David Keeney for helping out with this.
---
 .../flamenco_worker/cli.py                    |  4 +++
 .../flamenco_worker/patch_asyncio.py          | 29 +++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 packages/flamenco-worker-python/flamenco_worker/patch_asyncio.py

diff --git a/packages/flamenco-worker-python/flamenco_worker/cli.py b/packages/flamenco-worker-python/flamenco_worker/cli.py
index 46544be0..fbc80bb9 100644
--- a/packages/flamenco-worker-python/flamenco_worker/cli.py
+++ b/packages/flamenco-worker-python/flamenco_worker/cli.py
@@ -24,6 +24,10 @@ def main():
     log = logging.getLogger(__name__)
     log.debug('Starting')
 
+    # Patch AsyncIO
+    from . import patch_asyncio
+    patch_asyncio.patch_asyncio()
+
     # Construct the AsyncIO loop
     loop = construct_asyncio_loop()
     if args.verbose:
diff --git a/packages/flamenco-worker-python/flamenco_worker/patch_asyncio.py b/packages/flamenco-worker-python/flamenco_worker/patch_asyncio.py
new file mode 100644
index 00000000..f4843c6c
--- /dev/null
+++ b/packages/flamenco-worker-python/flamenco_worker/patch_asyncio.py
@@ -0,0 +1,29 @@
+"""
+Patches a safer version of resume_reading into the asyncio.unix_events._UnixReadPipeTransport class.
+
+This prevents an error at the end of a subprocess execution:
+
+    File "/usr/lib/python3.x/asyncio/unix_events.py", line 364, in resume_reading
+       self._loop.add_reader(self._fileno, self._read_ready)
+    AttributeError: 'NoneType' object has no attribute 'add_reader'
+
+"""
+
+import asyncio.unix_events as ue
+
+
+def patch_asyncio():
+    import logging
+
+    log = logging.getLogger(__name__)
+    log.debug('Patching ue._UnixReadPipeTransport.resume_reading')
+
+    orig_resume_reading = ue._UnixReadPipeTransport.resume_reading
+
+    def resume_reading(self, *args, **kwargs):
+        if not self._loop:
+            return
+
+        return orig_resume_reading(*args, **kwargs)
+
+    ue._UnixReadPipeTransport.resume_reading = resume_reading
-- 
GitLab