Fix review nits from PR #460 self-review
Address the actionable findings from the `/code-review` pass (#1-6); the d2-ext + docstring nits (#7-10) are left for a follow-up. Deats, - `uds_transport_actor_tree.py`: `portal.chan.raddr.sockpath` is the *shared listener* socket (named for the root registrar), NOT the child's path — relabel it + lead with the per-child peer pid, and stop claiming it's the child addr in the docstring, - `docs.yml`: scope the `pages` `concurrency` group to the `deploy` job w/ `cancel-in-progress: false` so a PR build can't cancel an in-flight production deploy, - `architecture.rst`: `'subint'` is not a selectable `start_method` on this branch (`SpawnMethodKey` lacks it) — reframe as in-development/roadmap, - `context.rst`: `StreamOverrun` isn't re-exported from `tractor`; point at `tractor._exceptions`, - `debugging/`: sweep the 3 literalinclude'd examples off the deprecated `.result()` -> `.wait_for_result()`, - `quickstart.rst`: proc-title is `name@pid` (per `Aid.reprol`), not `@uuid`. NOTE, the `debugging/` examples are pexpect-tested; re-run `tests/devx/test_debugger.py` for them. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
parent
ea982875a5
commit
37e7470f26
|
|
@ -17,11 +17,6 @@ permissions:
|
|||
pages: write
|
||||
id-token: write
|
||||
|
||||
# never run >1 pages deploy at once
|
||||
concurrency:
|
||||
group: 'pages'
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: 'sphinx build'
|
||||
|
|
@ -52,6 +47,12 @@ jobs:
|
|||
name: 'deploy to gh-pages'
|
||||
if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
|
||||
needs: build
|
||||
# serialize deploys but NEVER cancel an in-flight one
|
||||
# mid-upload; queue the next instead (scoped to this job so
|
||||
# PR builds can't cancel a production deploy).
|
||||
concurrency:
|
||||
group: 'pages'
|
||||
cancel-in-progress: false
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
|
|
|
|||
|
|
@ -192,13 +192,14 @@ spawn backend, selected with the ``start_method`` kwarg to
|
|||
names (forkserver is posix-only). Mostly interesting for
|
||||
ecosystem compat and start-up-latency tuning.
|
||||
|
||||
``'subint'`` (experimental, py3.14+)
|
||||
Each actor runs as a `PEP 734`_ sub-interpreter
|
||||
(``concurrent.interpreters``) driven on its own OS thread
|
||||
*inside the parent process*: interpreter-level
|
||||
shared-nothing isolation with much faster start-up. Yes,
|
||||
this bends the one-actor-one-process rule; the rest of the
|
||||
model is unchanged.
|
||||
``'subint'`` (in development, py3.14+)
|
||||
On the roadmap (not yet selectable via ``start_method`` on
|
||||
this release): run each actor as a `PEP 734`_
|
||||
sub-interpreter (``concurrent.interpreters``) driven on its
|
||||
own OS thread *inside the parent process* — interpreter-level
|
||||
shared-nothing isolation with much faster start-up. Yes, this
|
||||
bends the one-actor-one-process rule; the rest of the model
|
||||
is unchanged.
|
||||
|
||||
The ``TRACTOR_SPAWN_METHOD`` env-var beats any caller-passed
|
||||
``start_method``, so you can swap backends under an unmodified
|
||||
|
|
|
|||
|
|
@ -302,9 +302,9 @@ Overruns and backpressure
|
|||
|
||||
Stream msgs land in a bounded per-context buffer on the receiver
|
||||
side. A sender that outpaces a non-consuming receiver *overruns*
|
||||
it and the runtime raises :exc:`tractor.StreamOverrun` (also a
|
||||
:exc:`trio.TooSlowError`) instead of buffering without bound — SC
|
||||
discipline applies to memory too.
|
||||
it and the runtime raises ``StreamOverrun`` (from
|
||||
``tractor._exceptions``; also a :exc:`trio.TooSlowError`) instead
|
||||
of buffering without bound — SC discipline applies to memory too.
|
||||
|
||||
Your knobs:
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ breakfast - run this while monitoring your process tree::
|
|||
|
||||
Every subactor (best-effort, via the optional
|
||||
``setproctitle`` dep) re-titles its OS process like
|
||||
``_subactor[worker_0@<uuid>]``, so ``pstree``/``htop``/
|
||||
``_subactor[worker_0@<pid>]``, so ``pstree``/``htop``/
|
||||
``pgrep -f`` can tell your actors apart at a glance.
|
||||
|
||||
You'll see something like::
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ async def main():
|
|||
portal: tractor.Portal = await n.run_in_actor(
|
||||
cancelled_before_pause,
|
||||
)
|
||||
await portal.result()
|
||||
await portal.wait_for_result()
|
||||
|
||||
# ensure the same works in the root actor!
|
||||
await pm_on_cancelled()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ async def main():
|
|||
portal = await n.run_in_actor(
|
||||
breakpoint_forever,
|
||||
)
|
||||
await portal.result()
|
||||
await portal.wait_for_result()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ async def main():
|
|||
p: tractor.Portal = await an.run_in_actor(name_error)
|
||||
|
||||
# with this style, should raise on this line
|
||||
await p.result()
|
||||
await p.wait_for_result()
|
||||
|
||||
# with this alt style should raise at `open_nusery()`
|
||||
# return await p.result()
|
||||
# return await p.wait_for_result()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Demonstrate an actor tree which talks over unix-domain-socket
|
|||
`enable_transports=['uds']` when opening the root and every
|
||||
subactor inherits the preference.
|
||||
|
||||
The child's channel address is a filesystem socket path (no
|
||||
TCP port in sight!) and, as a kernel-provided bonus, the
|
||||
peer's pid is exchanged for free via `SO_PEERCRED`.
|
||||
Every channel address is a filesystem socket path (no TCP port
|
||||
in sight!) and, as a kernel-provided bonus, the peer's pid is
|
||||
exchanged for free via `SO_PEERCRED`.
|
||||
|
||||
'''
|
||||
import os
|
||||
|
|
@ -38,12 +38,17 @@ async def main() -> None:
|
|||
# filesystem socket path, NOT a (host, port) pair!
|
||||
raddr = portal.chan.raddr
|
||||
assert raddr.proto_key == 'uds'
|
||||
# NOTE, `.sockpath` is the *shared listener* socket file
|
||||
# (named for the root registrar) this channel rode in
|
||||
# on, NOT a per-child path; the child-specific identity
|
||||
# we get for free is the kernel-reported peer pid (via
|
||||
# `SO_PEERCRED`).
|
||||
print(
|
||||
f'portal chan tpt proto: {raddr.proto_key!r}\n'
|
||||
f'portal chan sock file: {raddr.sockpath}\n'
|
||||
f'listener sock file: {raddr.sockpath}\n'
|
||||
f'kernel-reported peer pid: {raddr.maybe_pid}\n'
|
||||
)
|
||||
# ask the child for its own bind addr: also a
|
||||
# ask the child for its OWN distinct bind addr: another
|
||||
# socket-file path under the runtime dir.
|
||||
print(f'child says: {await portal.run(report_addr)}')
|
||||
await portal.cancel_actor()
|
||||
|
|
|
|||
Loading…
Reference in New Issue