|
1 | 1 | import json
|
2 | 2 | from concurrent.futures import ThreadPoolExecutor
|
| 3 | +from inspect import isawaitable |
3 | 4 |
|
4 | 5 | import psutil
|
5 |
| -import zmq |
| 6 | +import zmq.asyncio |
6 | 7 | from jupyter_client.jsonutil import date_default
|
7 | 8 | from jupyter_server.base.handlers import APIHandler
|
8 |
| -from jupyter_server.utils import url_path_join |
9 | 9 | from packaging import version
|
10 | 10 | from tornado import web
|
11 | 11 | from tornado.concurrent import run_on_executor
|
12 | 12 |
|
13 |
| -try: |
14 |
| - # Traitlets >= 4.3.3 |
15 |
| - from traitlets import Callable |
16 |
| -except ImportError: |
17 |
| - from .utils import Callable |
18 |
| - |
19 | 13 |
|
20 | 14 | try:
|
21 | 15 | import ipykernel
|
|
24 | 18 | except ImportError:
|
25 | 19 | USAGE_IS_SUPPORTED = False
|
26 | 20 |
|
27 |
| -MAX_RETRIES = 3 |
28 |
| - |
29 | 21 |
|
30 | 22 | class ApiHandler(APIHandler):
|
31 | 23 | executor = ThreadPoolExecutor(max_workers=5)
|
@@ -113,17 +105,18 @@ async def get(self, matched_part=None, *args, **kwargs):
|
113 | 105 | usage_request = session.msg("usage_request", {})
|
114 | 106 |
|
115 | 107 | control_channel.send(usage_request)
|
116 |
| - poller = zmq.Poller() |
| 108 | + poller = zmq.asyncio.Poller() |
117 | 109 | control_socket = control_channel.socket
|
118 | 110 | poller.register(control_socket, zmq.POLLIN)
|
119 |
| - for i in range(1, MAX_RETRIES + 1): |
120 |
| - timeout_ms = 1000 * i |
121 |
| - events = dict(poller.poll(timeout_ms)) |
122 |
| - if not events: |
123 |
| - self.write(json.dumps({})) |
124 |
| - break |
125 |
| - if control_socket not in events: |
126 |
| - continue |
127 |
| - res = await client.control_channel.get_msg(timeout=0) |
| 111 | + # previous behavior was 3 retries: 1 + 2 + 3 = 6 seconds |
| 112 | + timeout_ms = 6_000 |
| 113 | + events = dict(await poller.poll(timeout_ms)) |
| 114 | + if control_socket not in events: |
| 115 | + self.write(json.dumps({})) |
| 116 | + else: |
| 117 | + res = client.control_channel.get_msg(timeout=0) |
| 118 | + if isawaitable(res): |
| 119 | + # control_channel.get_msg may return a Future, |
| 120 | + # depending on configured KernelManager class |
| 121 | + res = await res |
128 | 122 | self.write(json.dumps(res, default=date_default))
|
129 |
| - break |
0 commit comments