Compare commits
No commits in common. "0a3c48fc57989a12fb17baf1072c67834f7287c8" and "37e7470f265dfbaed996ebe45404bfefb7f6478b" have entirely different histories.
0a3c48fc57
...
37e7470f26
1
NEWS.rst
1
NEWS.rst
|
|
@ -78,7 +78,6 @@ Bug Fixes
|
||||||
for ``asyncio``-side errors to not propagate due to a race condition.
|
for ``asyncio``-side errors to not propagate due to a race condition.
|
||||||
|
|
||||||
The implementation fix summary is:
|
The implementation fix summary is:
|
||||||
|
|
||||||
- add state to signal the end of the ``trio`` side task to be
|
- add state to signal the end of the ``trio`` side task to be
|
||||||
read by the ``asyncio`` side and always cancel any ongoing
|
read by the ``asyncio`` side and always cancel any ongoing
|
||||||
task in such cases.
|
task in such cases.
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,6 @@ Rendering policy,
|
||||||
emitted as a literal block so no content is ever
|
emitted as a literal block so no content is ever
|
||||||
silently dropped.
|
silently dropped.
|
||||||
|
|
||||||
A render that is *attempted and fails* (a ``d2`` bin is
|
|
||||||
present but errors on the source) is NOT silently
|
|
||||||
degraded to the stale committed SVG: it raises a
|
|
||||||
docutils error (so ``sphinx-build -W`` fails the
|
|
||||||
build). The render is also atomic — a failed/torn
|
|
||||||
render can never clobber a good committed SVG — so the
|
|
||||||
last-good diagram survives a bad edit.
|
|
||||||
|
|
||||||
Binary discovery order,
|
Binary discovery order,
|
||||||
|
|
||||||
- the ``D2_BIN`` env var; may contain args which are
|
- the ``D2_BIN`` env var; may contain args which are
|
||||||
|
|
@ -45,13 +37,11 @@ Usage,
|
||||||
'''
|
'''
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import enum
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
@ -65,22 +55,6 @@ log = logging.getLogger(__name__)
|
||||||
# git-committed, fallback SVG outputs.
|
# git-committed, fallback SVG outputs.
|
||||||
_outdir: str = '_diagrams'
|
_outdir: str = '_diagrams'
|
||||||
|
|
||||||
# per-build map of {output-svg-name: source-relpath} used
|
|
||||||
# to detect 2 distinct `.d2` sources colliding on a single
|
|
||||||
# output stem; reset on each `builder-inited` (see `setup`).
|
|
||||||
_seen_outputs: dict[str, str] = {}
|
|
||||||
|
|
||||||
|
|
||||||
class RenderResult(enum.Enum):
|
|
||||||
'''
|
|
||||||
Outcome of a `render_svg()` call.
|
|
||||||
|
|
||||||
'''
|
|
||||||
OK = 'ok' # fresh SVG exists on disk
|
|
||||||
FELL_BACK = 'fell_back' # no bin; serving committed SVG
|
|
||||||
NO_OUTPUT = 'no_output' # no bin AND no committed SVG
|
|
||||||
FAILED = 'failed' # bin present, render errored
|
|
||||||
|
|
||||||
|
|
||||||
def find_d2(
|
def find_d2(
|
||||||
app: Sphinx,
|
app: Sphinx,
|
||||||
|
|
@ -103,54 +77,37 @@ def render_svg(
|
||||||
app: Sphinx,
|
app: Sphinx,
|
||||||
src: Path,
|
src: Path,
|
||||||
out: Path,
|
out: Path,
|
||||||
) -> RenderResult:
|
) -> bool:
|
||||||
'''
|
'''
|
||||||
Maybe (re)render `src` -> `out` and report the
|
Maybe (re)render `src` -> `out`, returning
|
||||||
outcome as a `RenderResult`.
|
`True` when an up-to-date SVG exists after the
|
||||||
|
call.
|
||||||
A render is performed only when `out` is missing or
|
|
||||||
older than `src` AND a `d2` binary is available. The
|
|
||||||
write is atomic (temp-file + `os.replace`) so a
|
|
||||||
failed or torn render never clobbers an existing
|
|
||||||
(committed) SVG.
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
fresh: bool = (
|
stale: bool = (
|
||||||
out.exists()
|
not out.exists()
|
||||||
and
|
or
|
||||||
src.stat().st_mtime <= out.stat().st_mtime
|
src.stat().st_mtime > out.stat().st_mtime
|
||||||
)
|
)
|
||||||
if fresh:
|
if not stale:
|
||||||
return RenderResult.OK
|
return True
|
||||||
d2cmd: list[str]|None = find_d2(app)
|
d2cmd: list[str]|None = find_d2(app)
|
||||||
if d2cmd is None:
|
if d2cmd is None:
|
||||||
# no binary: fall back to whatever is committed,
|
|
||||||
# else signal the caller to emit the raw source.
|
|
||||||
if out.exists():
|
if out.exists():
|
||||||
log.info(
|
log.info(
|
||||||
f'no d2 binary; using committed svg '
|
f'no d2 binary; using committed svg '
|
||||||
f'for {src.name}'
|
f'for {src.name}'
|
||||||
)
|
)
|
||||||
return RenderResult.FELL_BACK
|
return True
|
||||||
return RenderResult.NO_OUTPUT
|
return False
|
||||||
out.parent.mkdir(
|
out.parent.mkdir(
|
||||||
parents=True,
|
parents=True,
|
||||||
exist_ok=True,
|
exist_ok=True,
|
||||||
)
|
)
|
||||||
# render into a sibling temp-file first so a bad
|
|
||||||
# `d2` exit (or a crash mid-write) leaves any prior
|
|
||||||
# committed SVG fully intact.
|
|
||||||
fd, tmpname = tempfile.mkstemp(
|
|
||||||
dir=str(out.parent),
|
|
||||||
prefix=f'.{out.stem}.',
|
|
||||||
suffix='.svg.tmp',
|
|
||||||
)
|
|
||||||
os.close(fd)
|
|
||||||
tmp = Path(tmpname)
|
|
||||||
argv: list[str] = (
|
argv: list[str] = (
|
||||||
d2cmd
|
d2cmd
|
||||||
+ list(app.config.d2_args)
|
+ list(app.config.d2_args)
|
||||||
+ [str(src), str(tmp)]
|
+ [str(src), str(out)]
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
proc = sp.run(
|
proc = sp.run(
|
||||||
|
|
@ -163,22 +120,18 @@ def render_svg(
|
||||||
OSError,
|
OSError,
|
||||||
sp.TimeoutExpired,
|
sp.TimeoutExpired,
|
||||||
) as err:
|
) as err:
|
||||||
tmp.unlink(missing_ok=True)
|
|
||||||
log.warning(
|
log.warning(
|
||||||
f'd2 invocation failed for {src.name}: '
|
f'd2 invocation failed for {src.name}: '
|
||||||
f'{err}'
|
f'{err}'
|
||||||
)
|
)
|
||||||
return RenderResult.FAILED
|
return out.exists()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
tmp.unlink(missing_ok=True)
|
|
||||||
log.warning(
|
log.warning(
|
||||||
f'd2 render error for {src.name}:\n'
|
f'd2 render error for {src.name}:\n'
|
||||||
f'{proc.stderr}'
|
f'{proc.stderr}'
|
||||||
)
|
)
|
||||||
return RenderResult.FAILED
|
return out.exists()
|
||||||
# atomic swap-in of the freshly rendered SVG.
|
return True
|
||||||
os.replace(tmp, out)
|
|
||||||
return RenderResult.OK
|
|
||||||
|
|
||||||
|
|
||||||
class D2Diagram(SphinxDirective):
|
class D2Diagram(SphinxDirective):
|
||||||
|
|
@ -216,54 +169,18 @@ class D2Diagram(SphinxDirective):
|
||||||
/ _outdir
|
/ _outdir
|
||||||
/ f'{src.stem}.svg'
|
/ f'{src.stem}.svg'
|
||||||
)
|
)
|
||||||
# collision guard: two distinct sources must not
|
if not render_svg(self.env.app, src, out):
|
||||||
# map onto the same output stem within a build.
|
# last resort: emit the raw d2 source.
|
||||||
prior: str|None = _seen_outputs.get(out.name)
|
|
||||||
if (
|
|
||||||
prior is not None
|
|
||||||
and
|
|
||||||
prior != relsrc
|
|
||||||
):
|
|
||||||
err = self.state_machine.reporter.error(
|
|
||||||
f'd2 output collision: {relsrc!r} and '
|
|
||||||
f'{prior!r} both render to '
|
|
||||||
f'{_outdir}/{out.name}; rename one '
|
|
||||||
f'`.d2` stem',
|
|
||||||
line=self.lineno,
|
|
||||||
)
|
|
||||||
return [err]
|
|
||||||
_seen_outputs[out.name] = relsrc
|
|
||||||
|
|
||||||
result: RenderResult = render_svg(
|
|
||||||
self.env.app,
|
|
||||||
src,
|
|
||||||
out,
|
|
||||||
)
|
|
||||||
if result is RenderResult.FAILED:
|
|
||||||
# loud, build-failing (under `-W`) signal; the
|
|
||||||
# prior committed SVG, if any, is untouched.
|
|
||||||
err = self.state_machine.reporter.error(
|
|
||||||
f'd2 render failed for {relsrc} (see '
|
|
||||||
f'build log); the committed svg, if any, '
|
|
||||||
f'was left untouched',
|
|
||||||
line=self.lineno,
|
|
||||||
)
|
|
||||||
return [err]
|
|
||||||
if result is RenderResult.NO_OUTPUT:
|
|
||||||
# last resort: emit the raw d2 source so no
|
|
||||||
# content is ever silently dropped.
|
|
||||||
log.warning(
|
log.warning(
|
||||||
f'no svg available for {relsrc}; '
|
f'no svg available for {relsrc}; '
|
||||||
f'emitting d2 source as literal block'
|
f'emitting d2 source as literal block'
|
||||||
)
|
)
|
||||||
src_text: str = src.read_text()
|
|
||||||
literal = nodes.literal_block(
|
literal = nodes.literal_block(
|
||||||
src_text,
|
src.read_text(),
|
||||||
src_text,
|
src.read_text(),
|
||||||
)
|
)
|
||||||
literal['language'] = 'text'
|
literal['language'] = 'text'
|
||||||
return [literal]
|
return [literal]
|
||||||
# OK | FELL_BACK -> embed the SVG figure.
|
|
||||||
img = nodes.image(
|
img = nodes.image(
|
||||||
uri=f'/{_outdir}/{out.name}',
|
uri=f'/{_outdir}/{out.name}',
|
||||||
alt=self.options.get(
|
alt=self.options.get(
|
||||||
|
|
@ -307,29 +224,12 @@ class D2Diagram(SphinxDirective):
|
||||||
return [fig]
|
return [fig]
|
||||||
|
|
||||||
|
|
||||||
def _reset_seen(
|
|
||||||
app: Sphinx,
|
|
||||||
) -> None:
|
|
||||||
'''
|
|
||||||
Clear the per-build output-collision map at the
|
|
||||||
start of each build.
|
|
||||||
|
|
||||||
'''
|
|
||||||
_seen_outputs.clear()
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app: Sphinx) -> dict:
|
def setup(app: Sphinx) -> dict:
|
||||||
app.add_config_value('d2_bin', None, 'env')
|
app.add_config_value('d2_bin', None, 'env')
|
||||||
app.add_config_value('d2_args', [], 'env')
|
app.add_config_value('d2_args', [], 'env')
|
||||||
app.add_directive('d2', D2Diagram)
|
app.add_directive('d2', D2Diagram)
|
||||||
app.connect('builder-inited', _reset_seen)
|
|
||||||
return {
|
return {
|
||||||
'version': '0.1.0',
|
'version': '0.1.0',
|
||||||
# NB: run() writes the rendered SVG during the
|
|
||||||
# READ phase; the temp-file + `os.replace` swap
|
|
||||||
# keeps that atomic so concurrent renders of the
|
|
||||||
# same diagram (under `sphinx-build -j`) can't
|
|
||||||
# tear the output file.
|
|
||||||
'parallel_read_safe': True,
|
'parallel_read_safe': True,
|
||||||
'parallel_write_safe': True,
|
'parallel_write_safe': True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
flake.nix
30
flake.nix
|
|
@ -25,11 +25,11 @@
|
||||||
cpython = "python313";
|
cpython = "python313";
|
||||||
venv_dir = "py313";
|
venv_dir = "py313";
|
||||||
pypkgs = pkgs."${cpython}Packages";
|
pypkgs = pkgs."${cpython}Packages";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
|
||||||
# shared base toolchain for every dev-shell variant;
|
packages = [
|
||||||
# extra-tooling shells (eg. `docs`, below) extend it
|
|
||||||
# so heavy/niche deps stay OUT of the `default` shell.
|
|
||||||
basePkgs = [
|
|
||||||
# XXX, ensure sh completions activate!
|
# XXX, ensure sh completions activate!
|
||||||
pkgs.bashInteractive
|
pkgs.bashInteractive
|
||||||
pkgs.bash-completion
|
pkgs.bash-completion
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
pkgs.${cpython}# ?TODO^ how to set from `cpython` above?
|
pkgs.${cpython}# ?TODO^ how to set from `cpython` above?
|
||||||
];
|
];
|
||||||
|
|
||||||
baseHook = ''
|
shellHook = ''
|
||||||
# unmask to debug **this** dev-shell-hook
|
# unmask to debug **this** dev-shell-hook
|
||||||
# set -e
|
# set -e
|
||||||
|
|
||||||
|
|
@ -63,26 +63,6 @@
|
||||||
# run the `nix develop` cmd with,
|
# run the `nix develop` cmd with,
|
||||||
# >> nix develop -c uv run xonsh
|
# >> nix develop -c uv run xonsh
|
||||||
'';
|
'';
|
||||||
in
|
|
||||||
{
|
|
||||||
default = pkgs.mkShell {
|
|
||||||
packages = basePkgs;
|
|
||||||
shellHook = baseHook;
|
|
||||||
};
|
|
||||||
|
|
||||||
# OPT-IN docs shell: `default` + the `d2` diagram
|
|
||||||
# renderer, kept OUT of `default` so casual dev shells
|
|
||||||
# don't pull it in. Enter with,
|
|
||||||
# >> nix develop .#docs
|
|
||||||
# then build (the `.. d2::` directive auto-detects the
|
|
||||||
# `d2` bin now on PATH; see `docs/_ext/d2diagrams.py`),
|
|
||||||
# >> uv run --group docs make -C docs html
|
|
||||||
docs = pkgs.mkShell {
|
|
||||||
packages = basePkgs ++ [ pkgs.d2 ];
|
|
||||||
shellHook = baseHook + ''
|
|
||||||
echo "[docs] d2 $(d2 --version) on PATH \
|
|
||||||
— build via: uv run --group docs make -C docs html"
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,6 @@ class Context:
|
||||||
communication context.
|
communication context.
|
||||||
|
|
||||||
(We've also considered other names and ideas:
|
(We've also considered other names and ideas:
|
||||||
|
|
||||||
- "communicating tasks scope": cts
|
- "communicating tasks scope": cts
|
||||||
- "distributed task scope": dts
|
- "distributed task scope": dts
|
||||||
- "communicating tasks context": ctc
|
- "communicating tasks context": ctc
|
||||||
|
|
@ -145,7 +144,6 @@ class Context:
|
||||||
|
|
||||||
NB: This class should **never be instatiated directly**, it is
|
NB: This class should **never be instatiated directly**, it is
|
||||||
allocated by the runtime in 2 ways:
|
allocated by the runtime in 2 ways:
|
||||||
|
|
||||||
- by entering `Portal.open_context()` which is the primary
|
- by entering `Portal.open_context()` which is the primary
|
||||||
public API for any "parent" task or,
|
public API for any "parent" task or,
|
||||||
- by the RPC machinery's `._rpc._invoke()` as a `ctx` arg
|
- by the RPC machinery's `._rpc._invoke()` as a `ctx` arg
|
||||||
|
|
@ -445,7 +443,6 @@ class Context:
|
||||||
'''
|
'''
|
||||||
Records whether cancellation has been requested for this context
|
Records whether cancellation has been requested for this context
|
||||||
by a call to `.cancel()` either due to,
|
by a call to `.cancel()` either due to,
|
||||||
|
|
||||||
- an explicit call by some local task,
|
- an explicit call by some local task,
|
||||||
- or an implicit call due to an error caught inside
|
- or an implicit call due to an error caught inside
|
||||||
the `Portal.open_context()` block.
|
the `Portal.open_context()` block.
|
||||||
|
|
@ -557,7 +554,6 @@ class Context:
|
||||||
Only as an FYI, in the "child" side case it can also be
|
Only as an FYI, in the "child" side case it can also be
|
||||||
set but never is readable by any task outside the RPC
|
set but never is readable by any task outside the RPC
|
||||||
machinery in `._invoke()` since,:
|
machinery in `._invoke()` since,:
|
||||||
|
|
||||||
- when a child side calls `.cancel()`, `._scope.cancel()`
|
- when a child side calls `.cancel()`, `._scope.cancel()`
|
||||||
is called immediately and handled specially inside
|
is called immediately and handled specially inside
|
||||||
`._invoke()` to raise a `ContextCancelled` which is then
|
`._invoke()` to raise a `ContextCancelled` which is then
|
||||||
|
|
@ -1037,8 +1033,8 @@ class Context:
|
||||||
`._scope.cancel()` and delivering an `ContextCancelled`
|
`._scope.cancel()` and delivering an `ContextCancelled`
|
||||||
ack msg in reponse.
|
ack msg in reponse.
|
||||||
|
|
||||||
**Behaviour:**
|
Behaviour:
|
||||||
|
---------
|
||||||
- after the far end cancels, the `.cancel()` calling side
|
- after the far end cancels, the `.cancel()` calling side
|
||||||
should receive a `ContextCancelled` with the
|
should receive a `ContextCancelled` with the
|
||||||
`.canceller: tuple` uid set to the current `Actor.aid.uid`.
|
`.canceller: tuple` uid set to the current `Actor.aid.uid`.
|
||||||
|
|
@ -1509,7 +1505,6 @@ class Context:
|
||||||
TODO->( this is doc-driven-dev content not yet actual ;P )
|
TODO->( this is doc-driven-dev content not yet actual ;P )
|
||||||
|
|
||||||
The final "outcome" from an IPC context which can be any of:
|
The final "outcome" from an IPC context which can be any of:
|
||||||
|
|
||||||
- some `outcome.Value` which boxes the returned output from the peer task's
|
- some `outcome.Value` which boxes the returned output from the peer task's
|
||||||
`@context`-decorated remote task-as-func, or
|
`@context`-decorated remote task-as-func, or
|
||||||
- an `outcome.Error` wrapping an exception raised that same RPC task
|
- an `outcome.Error` wrapping an exception raised that same RPC task
|
||||||
|
|
@ -2071,7 +2066,7 @@ async def open_context_from_portal(
|
||||||
allows for deterministic setup and teardown of a remotely
|
allows for deterministic setup and teardown of a remotely
|
||||||
scheduled task in another remote actor. Once opened, the 2 now
|
scheduled task in another remote actor. Once opened, the 2 now
|
||||||
"linked" tasks run completely in parallel in each actor's
|
"linked" tasks run completely in parallel in each actor's
|
||||||
runtime with their enclosing `trio.CancelScope`\\ s kept in
|
runtime with their enclosing `trio.CancelScope`s kept in
|
||||||
a synced state wherein if either side errors or cancels an
|
a synced state wherein if either side errors or cancels an
|
||||||
equivalent error is relayed to the other side via an SC-compat
|
equivalent error is relayed to the other side via an SC-compat
|
||||||
IPC protocol.
|
IPC protocol.
|
||||||
|
|
|
||||||
|
|
@ -824,8 +824,7 @@ class ContextCancelled(RemoteActorError):
|
||||||
- (simulating) an IPC transport network outage
|
- (simulating) an IPC transport network outage
|
||||||
- a (malicious) pkt sent specifically to cancel an actor's
|
- a (malicious) pkt sent specifically to cancel an actor's
|
||||||
runtime non-gracefully without ensuring ongoing RPC tasks are
|
runtime non-gracefully without ensuring ongoing RPC tasks are
|
||||||
incrementally cancelled as is done with::
|
incrementally cancelled as is done with:
|
||||||
|
|
||||||
`Actor`
|
`Actor`
|
||||||
|_`.cancel()`
|
|_`.cancel()`
|
||||||
|_`.cancel_soon()`
|
|_`.cancel_soon()`
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,6 @@ def open_crash_handler(
|
||||||
`typer` users so they can quickly wrap cmd endpoints which get
|
`typer` users so they can quickly wrap cmd endpoints which get
|
||||||
automatically wrapped to use the runtime's `debug_mode: bool`
|
automatically wrapped to use the runtime's `debug_mode: bool`
|
||||||
AND `pdbp.pm()` around any code that is PRE-runtime entry
|
AND `pdbp.pm()` around any code that is PRE-runtime entry
|
||||||
|
|
||||||
- any sync code which runs BEFORE the main call to
|
- any sync code which runs BEFORE the main call to
|
||||||
`trio.run()`.
|
`trio.run()`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ def mk_pdb() -> PdbREPL:
|
||||||
|
|
||||||
FURTHER, the `pdbp.Pdb` instance is configured to be `trio`
|
FURTHER, the `pdbp.Pdb` instance is configured to be `trio`
|
||||||
"compatible" from a SIGINT handling perspective; we mask out
|
"compatible" from a SIGINT handling perspective; we mask out
|
||||||
the default `pdb` handler and instead apply `trio`\\ s default
|
the default `pdb` handler and instead apply `trio`s default
|
||||||
which mostly addresses all issues described in:
|
which mostly addresses all issues described in:
|
||||||
|
|
||||||
- https://github.com/python-trio/trio/issues/1155
|
- https://github.com/python-trio/trio/issues/1155
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,6 @@ async def query_actor(
|
||||||
listening @ `regaddr`.
|
listening @ `regaddr`.
|
||||||
|
|
||||||
Yields a `tuple` of `(addr, reg_portal)` where,
|
Yields a `tuple` of `(addr, reg_portal)` where,
|
||||||
|
|
||||||
- `addr` is the transport protocol (socket) address or `None` if
|
- `addr` is the transport protocol (socket) address or `None` if
|
||||||
no entry under that name exists,
|
no entry under that name exists,
|
||||||
- `reg_portal` is the `Portal` (or `LocalPortal` when the
|
- `reg_portal` is the `Portal` (or `LocalPortal` when the
|
||||||
|
|
@ -440,7 +439,7 @@ async def wait_for_actor(
|
||||||
) -> AsyncGenerator[Portal, None]:
|
) -> AsyncGenerator[Portal, None]:
|
||||||
'''
|
'''
|
||||||
Wait on at least one peer actor to register `name` with the
|
Wait on at least one peer actor to register `name` with the
|
||||||
registrar, yield a `Portal` to the first registree.
|
registrar, yield a `Portal to the first registree.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
actor: Actor = current_actor()
|
actor: Actor = current_actor()
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ class MsgCodec(Struct):
|
||||||
A IPC msg interchange format lib's encoder + decoder pair.
|
A IPC msg interchange format lib's encoder + decoder pair.
|
||||||
|
|
||||||
Pretty much nothing more then delegation to underlying
|
Pretty much nothing more then delegation to underlying
|
||||||
`msgspec.<interchange-protocol>.Encoder/Decoder`\\ s for now.
|
`msgspec.<interchange-protocol>.Encoder/Decoder`s for now.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
_enc: msgpack.Encoder
|
_enc: msgpack.Encoder
|
||||||
|
|
|
||||||
|
|
@ -453,7 +453,7 @@ class Error(
|
||||||
# omit_defaults=True,
|
# omit_defaults=True,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
A pkt that wraps `RemoteActorError`\\ s for relay and raising.
|
A pkt that wraps `RemoteActorError`s for relay and raising.
|
||||||
|
|
||||||
Fields are 1-to-1 meta-data as needed originally by
|
Fields are 1-to-1 meta-data as needed originally by
|
||||||
`RemoteActorError.msgdata: dict` but now are defined here.
|
`RemoteActorError.msgdata: dict` but now are defined here.
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,6 @@ class ActorNursery:
|
||||||
'''
|
'''
|
||||||
Records whether cancellation has been requested for this
|
Records whether cancellation has been requested for this
|
||||||
actor-nursery by a call to `.cancel()` either due to,
|
actor-nursery by a call to `.cancel()` either due to,
|
||||||
|
|
||||||
- an explicit call by some actor-local-task,
|
- an explicit call by some actor-local-task,
|
||||||
- an implicit call due to an error/cancel emited inside
|
- an implicit call due to an error/cancel emited inside
|
||||||
the `tractor.open_nursery()` block.
|
the `tractor.open_nursery()` block.
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,12 @@ async def gather_contexts(
|
||||||
None,
|
None,
|
||||||
]:
|
]:
|
||||||
'''
|
'''
|
||||||
Concurrently enter a sequence of async context managers (`acm`\\ s),
|
Concurrently enter a sequence of async context managers (`acm`s),
|
||||||
each scheduled in a separate `trio.Task` and deliver their
|
each scheduled in a separate `trio.Task` and deliver their
|
||||||
unwrapped `yield`-ed values in the same order once all `@acm`\\ s
|
unwrapped `yield`-ed values in the same order once all `@acm`s
|
||||||
in every task have entered.
|
in every task have entered.
|
||||||
|
|
||||||
On exit, all `acm`\\ s are subsequently and concurrently exited with
|
On exit, all `acm`s are subsequently and concurrently exited with
|
||||||
**no order guarantees**.
|
**no order guarantees**.
|
||||||
|
|
||||||
This function is somewhat similar to a batch of non-blocking
|
This function is somewhat similar to a batch of non-blocking
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue