Skip to content

Commit 7a229c6

Browse files
authored
Merge pull request #853 from minrk/queue-abort
2 parents 97cf7bd + 23c3709 commit 7a229c6

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

ipykernel/kernelbase.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ async def execute_request(self, stream, ident, parent):
671671
self.log.debug("%s", reply_msg)
672672

673673
if not silent and reply_msg['content']['status'] == 'error' and stop_on_error:
674-
await self._abort_queues()
674+
self._abort_queues()
675675

676676
def do_execute(self, code, silent, store_history=True,
677677
user_expressions=None, allow_stdin=False):
@@ -974,13 +974,31 @@ def _topic(self, topic):
974974

975975
_aborting = Bool(False)
976976

977-
async def _abort_queues(self):
978-
self.shell_stream.flush()
977+
def _abort_queues(self):
978+
# while this flag is true,
979+
# execute requests will be aborted
979980
self._aborting = True
981+
self.log.info("Aborting queue")
982+
983+
# flush streams, so all currently waiting messages
984+
# are added to the queue
985+
self.shell_stream.flush()
986+
987+
# Callback to signal that we are done aborting
980988
def stop_aborting():
981989
self.log.info("Finishing abort")
982990
self._aborting = False
983-
asyncio.get_event_loop().call_later(self.stop_on_error_timeout, stop_aborting)
991+
992+
# put the stop-aborting event on the message queue
993+
# so that all messages already waiting in the queue are aborted
994+
# before we reset the flag
995+
schedule_stop_aborting = partial(self.schedule_dispatch, stop_aborting)
996+
997+
# if we have a delay, give messages this long to arrive on the queue
998+
# before we stop aborting requests
999+
asyncio.get_event_loop().call_later(
1000+
self.stop_on_error_timeout, schedule_stop_aborting
1001+
)
9841002

9851003
def _send_abort_reply(self, stream, msg, idents):
9861004
"""Send a reply to an aborted request"""

ipykernel/tests/test_message_spec.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,15 +341,23 @@ def test_execute_stop_on_error():
341341
"""execute request should not abort execution queue with stop_on_error False"""
342342
flush_channels()
343343

344-
fail = '\n'.join([
345-
# sleep to ensure subsequent message is waiting in the queue to be aborted
346-
'import time',
347-
'time.sleep(0.5)',
348-
'raise ValueError',
349-
])
344+
fail = "\n".join(
345+
[
346+
# sleep to ensure subsequent message is waiting in the queue to be aborted
347+
# async sleep to ensure coroutines are processing while this happens
348+
"import asyncio",
349+
"await asyncio.sleep(1)",
350+
"raise ValueError()",
351+
]
352+
)
350353
KC.execute(code=fail)
351354
KC.execute(code='print("Hello")')
352-
KC.get_shell_msg(timeout=TIMEOUT)
355+
KC.execute(code='print("world")')
356+
reply = KC.get_shell_msg(timeout=TIMEOUT)
357+
print(reply)
358+
reply = KC.get_shell_msg(timeout=TIMEOUT)
359+
assert reply["content"]["status"] == "aborted"
360+
# second message, too
353361
reply = KC.get_shell_msg(timeout=TIMEOUT)
354362
assert reply['content']['status'] == 'aborted'
355363

0 commit comments

Comments
 (0)