|
12 | 12 | import warnings
|
13 | 13 | from collections.abc import Iterable
|
14 | 14 | from concurrent.futures import Future
|
| 15 | +from contextlib import contextmanager |
15 | 16 | from getpass import getpass
|
16 | 17 | from pprint import pprint
|
17 | 18 | from threading import current_thread
|
@@ -990,21 +991,59 @@ def _stop_io_thread(self):
|
990 | 991 | self._io_thread.join()
|
991 | 992 |
|
992 | 993 | def _setup_streams(self):
|
993 |
| - self._query_stream = ZMQStream(self._query_socket, self._io_loop) |
994 |
| - self._query_stream.on_recv(self._dispatch_single_reply, copy=False) |
995 |
| - self._control_stream = ZMQStream(self._control_socket, self._io_loop) |
| 994 | + self._streams = [] # all streams |
| 995 | + self._engine_streams = [] # streams that talk to engines |
| 996 | + self._query_stream = s = ZMQStream(self._query_socket, self._io_loop) |
| 997 | + self._streams.append(s) |
| 998 | + self._notification_stream = s = ZMQStream( |
| 999 | + self._notification_socket, self._io_loop |
| 1000 | + ) |
| 1001 | + self._streams.append(s) |
| 1002 | + |
| 1003 | + self._control_stream = s = ZMQStream(self._control_socket, self._io_loop) |
| 1004 | + self._streams.append(s) |
| 1005 | + self._engine_streams.append(s) |
| 1006 | + self._mux_stream = s = ZMQStream(self._mux_socket, self._io_loop) |
| 1007 | + self._streams.append(s) |
| 1008 | + self._engine_streams.append(s) |
| 1009 | + self._task_stream = s = ZMQStream(self._task_socket, self._io_loop) |
| 1010 | + self._streams.append(s) |
| 1011 | + self._engine_streams.append(s) |
| 1012 | + self._broadcast_stream = s = ZMQStream(self._broadcast_socket, self._io_loop) |
| 1013 | + self._streams.append(s) |
| 1014 | + self._engine_streams.append(s) |
| 1015 | + self._iopub_stream = s = ZMQStream(self._iopub_socket, self._io_loop) |
| 1016 | + self._streams.append(s) |
| 1017 | + self._engine_streams.append(s) |
| 1018 | + self._start_receiving(all=True) |
| 1019 | + |
| 1020 | + def _start_receiving(self, all=False): |
| 1021 | + """Start receiving on streams |
| 1022 | +
|
| 1023 | + default: only engine streams |
| 1024 | +
|
| 1025 | + if all: include hub streams |
| 1026 | + """ |
| 1027 | + if all: |
| 1028 | + self._query_stream.on_recv(self._dispatch_single_reply, copy=False) |
| 1029 | + self._notification_stream.on_recv(self._dispatch_notification, copy=False) |
996 | 1030 | self._control_stream.on_recv(self._dispatch_single_reply, copy=False)
|
997 |
| - self._mux_stream = ZMQStream(self._mux_socket, self._io_loop) |
998 | 1031 | self._mux_stream.on_recv(self._dispatch_reply, copy=False)
|
999 |
| - self._task_stream = ZMQStream(self._task_socket, self._io_loop) |
1000 | 1032 | self._task_stream.on_recv(self._dispatch_reply, copy=False)
|
1001 |
| - self._iopub_stream = ZMQStream(self._iopub_socket, self._io_loop) |
| 1033 | + self._broadcast_stream.on_recv(self._dispatch_reply, copy=False) |
1002 | 1034 | self._iopub_stream.on_recv(self._dispatch_iopub, copy=False)
|
1003 |
| - self._notification_stream = ZMQStream(self._notification_socket, self._io_loop) |
1004 |
| - self._notification_stream.on_recv(self._dispatch_notification, copy=False) |
1005 | 1035 |
|
1006 |
| - self._broadcast_stream = ZMQStream(self._broadcast_socket, self._io_loop) |
1007 |
| - self._broadcast_stream.on_recv(self._dispatch_reply, copy=False) |
| 1036 | + def _stop_receiving(self, all=False): |
| 1037 | + """Stop receiving on engine streams |
| 1038 | +
|
| 1039 | + If all: include hub streams |
| 1040 | + """ |
| 1041 | + if all: |
| 1042 | + streams = self._streams |
| 1043 | + else: |
| 1044 | + streams = self._engine_streams |
| 1045 | + for s in streams: |
| 1046 | + s.stop_on_recv() |
1008 | 1047 |
|
1009 | 1048 | def _start_io_thread(self):
|
1010 | 1049 | """Start IOLoop in a background thread."""
|
@@ -1034,6 +1073,30 @@ def _io_main(self, start_evt=None):
|
1034 | 1073 | self._io_loop.start()
|
1035 | 1074 | self._io_loop.close()
|
1036 | 1075 |
|
| 1076 | + @contextmanager |
| 1077 | + def _pause_results(self): |
| 1078 | + """Context manager to pause receiving results |
| 1079 | +
|
| 1080 | + When submitting lots of tasks, |
| 1081 | + the arrival of results can disrupt the processing |
| 1082 | + of new submissions. |
| 1083 | +
|
| 1084 | + Threadsafe. |
| 1085 | + """ |
| 1086 | + f = Future() |
| 1087 | + |
| 1088 | + def _stop(): |
| 1089 | + self._stop_receiving() |
| 1090 | + f.set_result(None) |
| 1091 | + |
| 1092 | + # use add_callback to make it threadsafe |
| 1093 | + self._io_loop.add_callback(_stop) |
| 1094 | + f.result() |
| 1095 | + try: |
| 1096 | + yield |
| 1097 | + finally: |
| 1098 | + self._io_loop.add_callback(self._start_receiving) |
| 1099 | + |
1037 | 1100 | @unpack_message
|
1038 | 1101 | def _dispatch_single_reply(self, msg):
|
1039 | 1102 | """Dispatch single (non-execution) replies"""
|
|
0 commit comments