diff --git a/artiq/protocols/logging.py b/artiq/protocols/logging.py index f65212550..e69f76223 100644 --- a/artiq/protocols/logging.py +++ b/artiq/protocols/logging.py @@ -2,7 +2,7 @@ import asyncio import logging from artiq.protocols.asyncio_server import AsyncioServer -from artiq.tools import TaskObject +from artiq.tools import TaskObject, workaround_asyncio263 logger = logging.getLogger(__name__) @@ -119,19 +119,12 @@ class LogForwarder(logging.Handler, TaskObject): try: reader, writer = await asyncio.open_connection(self.host, self.port) - detect_close = asyncio.ensure_future(reader.read(1)) writer.write(_init_string) while True: message = await self._queue.get() + "\n" writer.write(message.encode()) + await workaround_asyncio263() await writer.drain() - # HACK: detect connection termination through the completion - # of a read operation. For some reason, write/drain operations - # on a closed socket do not raise exceptions, but print - # "asyncio:socket.send() raised exception." - if detect_close.done(): - await asyncio.sleep(self.reconnect_timer) - break except asyncio.CancelledError: return except: diff --git a/artiq/protocols/sync_struct.py b/artiq/protocols/sync_struct.py index e7100701d..e42534cdb 100644 --- a/artiq/protocols/sync_struct.py +++ b/artiq/protocols/sync_struct.py @@ -16,6 +16,7 @@ from functools import partial from artiq.protocols import pyon from artiq.protocols.asyncio_server import AsyncioServer +from artiq.tools import workaround_asyncio263 _init_string = b"ARTIQ sync_struct\n" @@ -233,6 +234,7 @@ class Publisher(AsyncioServer): line = await queue.get() writer.write(line) # raise exception on connection error + await workaround_asyncio263() await writer.drain() finally: self._recipients[notifier_name].remove(queue) diff --git a/artiq/tools.py b/artiq/tools.py index 3c2701e90..9e443fb6b 100644 --- a/artiq/tools.py +++ b/artiq/tools.py @@ -175,3 +175,9 @@ class Condition: for fut in self._waiters: if not fut.done(): fut.set_result(False) + + +# See: https://github.com/python/asyncio/issues/263 +@asyncio.coroutine +def workaround_asyncio263(): + yield