async-kernel 0.22.1__tar.gz → 0.22.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {async_kernel-0.22.1 → async_kernel-0.22.2}/CHANGELOG.md +18 -1
- {async_kernel-0.22.1 → async_kernel-0.22.2}/PKG-INFO +1 -1
- {async_kernel-0.22.1 → async_kernel-0.22.2}/_version.py +2 -2
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/caller.py +4 -4
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/zmq_poll.py +9 -6
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/interface/base.py +12 -9
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/messaging/zmq.py +15 -10
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/utils.py +8 -2
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/dependabot.yaml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/release.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/ci.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/enforce-label.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/new_release.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/pre-commit.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/publish-docs.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.github/workflows/publish-to-pypi.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.gitignore +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.pre-commit-config.yaml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.vscode/launch.json +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.vscode/settings.json +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/.vscode/spellright.dict +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/CONTRIBUTING.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/IPYTHON_LICENSE +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/LICENSE +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/README.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/cliff.toml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/about/changelog.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/about/contributing.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/about/index.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/about/license.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/index.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/javascripts/extra.js +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/notebooks/caller.ipynb +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/notebooks/concurrency.ipynb +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/notebooks/custom_kernel.ipynb +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/overrides/main.html +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/caller.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/comm.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/command.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/common.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/debugger.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/event_loop.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/index.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/interface.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/ipshell.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/kernel.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/kernelspec.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/messaging.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/pending.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/shell.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/typing.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/reference/utils.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/stylesheets/extra.css +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/thread_safety.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/usage/commands.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/docs/usage/index.md +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/hatch_build.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/mkdocs.yml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/pyproject.toml +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/__main__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/comm.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/command.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/common.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/compat/attr_docs.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/compat/json.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/compiler.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/debugger.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/asyncio_guest.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/qt_host.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/run.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/event_loop/tk_host.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/interface/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/interface/callable.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/interface/ip_app.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/kernel.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/kernelspec.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/messaging/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/messaging/base.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/outstream.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/pending.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/py.typed +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/resources/logo-32x32.png +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/resources/logo-64x64.png +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/resources/logo-svg.svg +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/shell/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/shell/base.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/shell/ipshell.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/typing.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/src/async_kernel/utils.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/__init__.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/conftest.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/references.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_callable_interface.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_caller.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_comm.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_command.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_common.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_compat.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_connection.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_debugger.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_debugger_static.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_enter_kernel.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_event_loop.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_eventloop_zmq_poll.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_interface.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_ipapp.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_kernel_ipshell.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_kernelspec.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_message_spec.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_outstream.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_pending.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_subclass.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_typing.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_utils.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_zmq_connection.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/tests/test_zmq_subprocess.py +0 -0
- {async_kernel-0.22.1 → async_kernel-0.22.2}/uv.lock +0 -0
|
@@ -5,7 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [0.22.
|
|
8
|
+
## [0.22.2] - 2026-08-21
|
|
9
|
+
|
|
10
|
+
### <!-- 1 --> 🚀 Features
|
|
11
|
+
|
|
12
|
+
- ZMQPoll._wake minor optimization. [#574](https://github.com/fleming79/async-kernel/pull/574)
|
|
13
|
+
|
|
14
|
+
- Replace BinarySemaphore with threading.Lock for faster performance in heavily used places. [#571](https://github.com/fleming79/async-kernel/pull/571)
|
|
15
|
+
|
|
16
|
+
### <!-- 6 --> 🌀 Miscellaneous
|
|
17
|
+
|
|
18
|
+
- Tweak Interface startup sequence. [#573](https://github.com/fleming79/async-kernel/pull/573)
|
|
19
|
+
|
|
20
|
+
- Alan Fleming Refactor ZMQConnection to send the welcome message directly. [#572](https://github.com/fleming79/async-kernel/pull/572)
|
|
21
|
+
|
|
22
|
+
## [0.22.1] - 2026-08-19
|
|
9
23
|
|
|
10
24
|
### <!-- 0 --> 🏗️ Breaking changes
|
|
11
25
|
|
|
@@ -17,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
31
|
|
|
18
32
|
### <!-- 6 --> 🌀 Miscellaneous
|
|
19
33
|
|
|
34
|
+
- Prepare for release v0.22.1 [#570](https://github.com/fleming79/async-kernel/pull/570)
|
|
35
|
+
|
|
20
36
|
- Refactor create_interface_messge_callback_handler to only use one connection [#569](https://github.com/fleming79/async-kernel/pull/569)
|
|
21
37
|
|
|
22
38
|
## [0.22.0] - 2026-08-17
|
|
@@ -1545,6 +1561,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1545
1561
|
|
|
1546
1562
|
- Bump the actions group across 1 directory with 2 updates [#3](https://github.com/fleming79/async-kernel/pull/3)
|
|
1547
1563
|
|
|
1564
|
+
[0.22.2]: https://github.com/fleming79/async-kernel/compare/v0.22.1..v0.22.2
|
|
1548
1565
|
[0.22.1]: https://github.com/fleming79/async-kernel/compare/v0.22.0..v0.22.1
|
|
1549
1566
|
[0.22.0]: https://github.com/fleming79/async-kernel/compare/v0.21.0..v0.22.0
|
|
1550
1567
|
[0.21.0]: https://github.com/fleming79/async-kernel/compare/v0.20.2..v0.21.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: async-kernel
|
|
3
|
-
Version: 0.22.
|
|
3
|
+
Version: 0.22.2
|
|
4
4
|
Summary: A concurrent python kernel for Jupyter supporting AnyIO, AsyncIO and Trio.
|
|
5
5
|
Project-URL: Homepage, https://fleming79.github.io/async-kernel
|
|
6
6
|
Project-URL: Documentation, https://fleming79.github.io/async-kernel
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.22.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 22,
|
|
21
|
+
__version__ = version = '0.22.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 22, 2)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -19,7 +19,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Generic, Literal,
|
|
|
19
19
|
from weakref import ReferenceType
|
|
20
20
|
|
|
21
21
|
import anyio
|
|
22
|
-
from aiologic import
|
|
22
|
+
from aiologic import CountdownEvent
|
|
23
23
|
from aiologic.lowlevel import async_checkpoint, create_async_event, current_async_library
|
|
24
24
|
from aiologic.meta import await_for, iscoroutinelike
|
|
25
25
|
from typing_extensions import override
|
|
@@ -191,7 +191,7 @@ class Caller:
|
|
|
191
191
|
|
|
192
192
|
_caller_token = contextvars.ContextVar("caller_tokens", default=CALLER_MAIN_THREAD_ID)
|
|
193
193
|
_instances: ClassVar[weakref.WeakValueDictionary[int, Self]] = weakref.WeakValueDictionary()
|
|
194
|
-
_lock: ClassVar =
|
|
194
|
+
_lock: ClassVar = threading.Lock()
|
|
195
195
|
|
|
196
196
|
_thread: threading.Thread
|
|
197
197
|
_caller_id: int
|
|
@@ -219,7 +219,7 @@ class Caller:
|
|
|
219
219
|
_worker_pool: Fixed[Self, deque[Self]] = Fixed(deque)
|
|
220
220
|
|
|
221
221
|
# Private
|
|
222
|
-
_inst_lock:
|
|
222
|
+
_inst_lock: threading.Lock
|
|
223
223
|
_children: set[Self]
|
|
224
224
|
_tasks: set[asyncio.Task]
|
|
225
225
|
_queue_map: dict[int, Pending]
|
|
@@ -394,7 +394,7 @@ class Caller:
|
|
|
394
394
|
thread = threading.current_thread()
|
|
395
395
|
|
|
396
396
|
# Add private objects
|
|
397
|
-
inst._inst_lock =
|
|
397
|
+
inst._inst_lock = threading.Lock()
|
|
398
398
|
inst._children = set()
|
|
399
399
|
inst._tasks = set()
|
|
400
400
|
inst._queue_map = {}
|
|
@@ -41,7 +41,7 @@ class ZMQPollSocket(zmq.sugar.Socket[bytes]):
|
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
_zmq_poll_ref: weakref.ref[ZMQPoll]
|
|
44
|
-
lock:
|
|
44
|
+
lock: threading.Lock
|
|
45
45
|
|
|
46
46
|
if TYPE_CHECKING:
|
|
47
47
|
# magic attributes cannot be be stored in `__annotations__`.
|
|
@@ -68,7 +68,7 @@ class ZMQPollSocket(zmq.sugar.Socket[bytes]):
|
|
|
68
68
|
zmq_poll: ZMQPoll,
|
|
69
69
|
copy_threshold: int | None = None,
|
|
70
70
|
) -> None:
|
|
71
|
-
self.lock =
|
|
71
|
+
self.lock = threading.Lock()
|
|
72
72
|
self._zmq_poll_ref = weakref.ref(zmq_poll)
|
|
73
73
|
|
|
74
74
|
if zmq_poll.stopped.done():
|
|
@@ -99,10 +99,13 @@ class ZMQPollSocket(zmq.sugar.Socket[bytes]):
|
|
|
99
99
|
track: bool = False,
|
|
100
100
|
**kwargs,
|
|
101
101
|
) -> MessageTracker | None:
|
|
102
|
-
|
|
102
|
+
self.lock.acquire()
|
|
103
|
+
try:
|
|
103
104
|
if self.closed:
|
|
104
105
|
return None
|
|
105
106
|
return super().send_multipart(msg_parts, flags, copy, track)
|
|
107
|
+
finally:
|
|
108
|
+
self.lock.release()
|
|
106
109
|
|
|
107
110
|
@override
|
|
108
111
|
def close(self, linger=None) -> None:
|
|
@@ -189,7 +192,6 @@ class ZMQPoll:
|
|
|
189
192
|
self._handlers: dict[T_key, Callable[[ZMQPollSocket, int], Any]] = {}
|
|
190
193
|
self._count: dict[T_key, tuple[int, Callable[[], Any]] | None] = {}
|
|
191
194
|
self._execute: deque[Pending] = deque[Pending[Any]]()
|
|
192
|
-
self._not_started = False
|
|
193
195
|
self.log = logging.LoggerAdapter(logging.getLogger())
|
|
194
196
|
self._cancellers = deque()
|
|
195
197
|
self._ctx_count = 0
|
|
@@ -321,8 +323,9 @@ class ZMQPoll:
|
|
|
321
323
|
send = started.wait_sync()
|
|
322
324
|
|
|
323
325
|
def _wake(sock=send, lock=send.lock) -> None:
|
|
324
|
-
|
|
325
|
-
|
|
326
|
+
lock.acquire()
|
|
327
|
+
sock.send(b"")
|
|
328
|
+
lock.release()
|
|
326
329
|
|
|
327
330
|
self._wake = _wake
|
|
328
331
|
self.stopped.add_done_callback(lambda _: (self := ref()) and self._on_stopped())
|
|
@@ -12,7 +12,7 @@ import weakref
|
|
|
12
12
|
from typing import TYPE_CHECKING, Any, Generic, Literal, Self, final
|
|
13
13
|
|
|
14
14
|
from aiologic import BinarySemaphore
|
|
15
|
-
from aiologic.lowlevel import AsyncLibraryNotFoundError, current_async_library
|
|
15
|
+
from aiologic.lowlevel import AsyncLibraryNotFoundError, async_checkpoint, current_async_library
|
|
16
16
|
from traitlets import import_item, traitlets
|
|
17
17
|
from traitlets.config import Config, Configurable
|
|
18
18
|
from traitlets.config.application import Application, ClassesType
|
|
@@ -395,19 +395,22 @@ class Interface(StartStopTask, Application, Generic[T_shell_co]):
|
|
|
395
395
|
await self._pre_start()
|
|
396
396
|
self.log.info("Interface started: %s", self.summary)
|
|
397
397
|
started()
|
|
398
|
-
|
|
398
|
+
# Allow connections to react to being started.
|
|
399
|
+
await async_checkpoint(force=True)
|
|
400
|
+
# Send iopub messages captured during startup.
|
|
401
|
+
del started, self.iopub_send
|
|
402
|
+
while self._iopub_cache:
|
|
403
|
+
self._iopub_cache.reverse()
|
|
404
|
+
args, kwargs = self._iopub_cache.pop()
|
|
405
|
+
self.iopub_send(*args, **kwargs)
|
|
399
406
|
await stop
|
|
400
407
|
|
|
401
408
|
async def _pre_start(self) -> None:
|
|
402
|
-
"""
|
|
409
|
+
"""Perform tasks just prior to setting as started."""
|
|
410
|
+
# Autostart connections waiting until they have started.
|
|
403
411
|
if pending := [import_item(pth)().start().started for pth in self.autostart_connections]:
|
|
404
412
|
self.log.info("Waiting for connections to establish %d", len(pending))
|
|
405
|
-
|
|
406
|
-
del self.iopub_send
|
|
407
|
-
while self._iopub_cache:
|
|
408
|
-
self._iopub_cache.reverse()
|
|
409
|
-
args, kwargs = self._iopub_cache.pop()
|
|
410
|
-
self.iopub_send(*args, **kwargs)
|
|
413
|
+
await self.caller.wait(pending)
|
|
411
414
|
|
|
412
415
|
def update_connections(self, *new: Connection[Self]) -> None:
|
|
413
416
|
"""Update the list of connections.
|
|
@@ -158,8 +158,8 @@ class ZMQConnection(ZMQMessage, Connection[T_interface_co], Generic[T_interface_
|
|
|
158
158
|
msg = socket.recv()
|
|
159
159
|
if msg[0] == 1:
|
|
160
160
|
ident = msg[1:]
|
|
161
|
-
|
|
162
|
-
self.
|
|
161
|
+
msg = self.msg(MsgType.iopub_welcome, {"subscription": ident.decode()}, Channel.iopub)
|
|
162
|
+
self.session.send(socket, msg, ident=[ident]) # pyright: ignore[reportArgumentType]
|
|
163
163
|
|
|
164
164
|
def handler(sock, event, channel: Channel, recv=self.session.recv, handle_msg=self.handle_incoming_msg) -> None:
|
|
165
165
|
# Thread: zmq_poll_thread
|
|
@@ -169,6 +169,9 @@ class ZMQConnection(ZMQMessage, Connection[T_interface_co], Generic[T_interface_
|
|
|
169
169
|
|
|
170
170
|
with self.zmq_poll as zpoll:
|
|
171
171
|
await self._bind_sockets()
|
|
172
|
+
self.parent.update_connections(self)
|
|
173
|
+
started()
|
|
174
|
+
await self.parent.started
|
|
172
175
|
with (
|
|
173
176
|
zpoll.event_handler(self._sockets[Channel.control], partial(handler, channel=Channel.control)),
|
|
174
177
|
zpoll.event_handler(self._sockets[Channel.shell], functools.partial(handler, channel=Channel.shell)),
|
|
@@ -176,7 +179,8 @@ class ZMQConnection(ZMQMessage, Connection[T_interface_co], Generic[T_interface_
|
|
|
176
179
|
zpoll.event_handler(self._sockets[Channel.heartbeat], heartbeat_handler),
|
|
177
180
|
zpoll.event_handler(self._sockets[Channel.iopub], iopub_reg_handler),
|
|
178
181
|
):
|
|
179
|
-
await
|
|
182
|
+
await stop
|
|
183
|
+
self.parent.update_connections()
|
|
180
184
|
|
|
181
185
|
async def _bind_sockets(self):
|
|
182
186
|
"""Create, configure and bind all sockets."""
|
|
@@ -395,7 +399,7 @@ class ZMQClient(BaseClient[T_interface_co], ZMQMessage, Generic[T_interface_co])
|
|
|
395
399
|
@asynccontextmanager
|
|
396
400
|
@override
|
|
397
401
|
async def iopub_subscribe(
|
|
398
|
-
self, topic=b"", *, timeout: float | None =
|
|
402
|
+
self, topic=b"", *, timeout: float | None = 10.0
|
|
399
403
|
) -> AsyncGenerator[SingleAsyncQueue[Message]]:
|
|
400
404
|
|
|
401
405
|
def forward_messages(sock: ZMQPollSocket, event: int) -> None:
|
|
@@ -414,10 +418,11 @@ class ZMQClient(BaseClient[T_interface_co], ZMQMessage, Generic[T_interface_co])
|
|
|
414
418
|
iopub = await self._connect_socket(Channel.iopub)
|
|
415
419
|
with iopub, self.zmq_poll.event_handler(iopub, forward_messages, canceller=canceller), scope:
|
|
416
420
|
iopub.subscribe(topic)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
421
|
+
if timeout is not None:
|
|
422
|
+
self.log.debug("Waiting for welcome message.")
|
|
423
|
+
if await ready.with_(timeout=timeout):
|
|
424
|
+
self.log.debug("Welcome message received.")
|
|
425
|
+
else:
|
|
426
|
+
msg = f"Welcome message not received after {timeout:0.1f}s!"
|
|
427
|
+
raise TimeoutError(msg)
|
|
423
428
|
yield queue
|
|
@@ -4,6 +4,7 @@ import importlib.util
|
|
|
4
4
|
import os
|
|
5
5
|
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
|
+
import anyio
|
|
7
8
|
import pytest
|
|
8
9
|
|
|
9
10
|
import async_kernel.utils
|
|
@@ -66,8 +67,13 @@ async def read_until_msg_type(reader: AsyncGenerator, msg_type: IOPubMsgTypeAlia
|
|
|
66
67
|
Args:
|
|
67
68
|
reader: An async iterator for a queue returned from iopub subscribe.
|
|
68
69
|
msg_type: The type of iopub message to wait for."""
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
try:
|
|
71
|
+
with anyio.fail_after(TIMEOUT):
|
|
72
|
+
while (msg := await anext(reader))["header"]["msg_type"] != msg_type:
|
|
73
|
+
continue
|
|
74
|
+
except TimeoutError as e:
|
|
75
|
+
msg_ = f"Timeout waiting for {msg_type=} {content_checks=}"
|
|
76
|
+
raise TimeoutError(msg_) from e
|
|
71
77
|
check_pub_message(msg, msg_type=msg_type, **content_checks)
|
|
72
78
|
return msg
|
|
73
79
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|