Compare commits
11 Commits
b875b35b98
...
fb04f74605
Author | SHA1 | Date |
---|---|---|
Tyler Goodlet | fb04f74605 | |
Tyler Goodlet | aa1f6fa4b5 | |
Tyler Goodlet | 9002f608ee | |
Tyler Goodlet | 8ebc022535 | |
Tyler Goodlet | e26fa8330f | |
Tyler Goodlet | a2659069c5 | |
Tyler Goodlet | 54699d7a0b | |
Tyler Goodlet | b91ab9e3a8 | |
Tyler Goodlet | cd14c4fe72 | |
Tyler Goodlet | ad40fcd2bc | |
Tyler Goodlet | 508ba510a5 |
|
@ -0,0 +1,18 @@
|
||||||
|
First generate a built disti:
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m pip install --upgrade build
|
||||||
|
python -m build --sdist --outdir dist/alpha5/
|
||||||
|
```
|
||||||
|
|
||||||
|
Then try a test ``pypi`` upload:
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m twine upload --repository testpypi dist/alpha5/*
|
||||||
|
```
|
||||||
|
|
||||||
|
The push to `pypi` for realz.
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m twine upload --repository testpypi dist/alpha5/*
|
||||||
|
```
|
|
@ -1703,15 +1703,28 @@ class Context:
|
||||||
# TODO: expose as mod func instead!
|
# TODO: expose as mod func instead!
|
||||||
structfmt = pretty_struct.Struct.pformat
|
structfmt = pretty_struct.Struct.pformat
|
||||||
if self._in_overrun:
|
if self._in_overrun:
|
||||||
log.warning(
|
report: str = (
|
||||||
f'Queueing OVERRUN msg on caller task:\n\n'
|
|
||||||
|
|
||||||
f'{flow_body}'
|
f'{flow_body}'
|
||||||
|
|
||||||
f'{structfmt(msg)}\n'
|
f'{structfmt(msg)}\n'
|
||||||
)
|
)
|
||||||
|
over_q: deque = self._overflow_q
|
||||||
self._overflow_q.append(msg)
|
self._overflow_q.append(msg)
|
||||||
|
|
||||||
|
if len(over_q) == over_q.maxlen:
|
||||||
|
report = (
|
||||||
|
'FAILED to queue OVERRUN msg, OVERAN the OVERRUN QUEUE !!\n\n'
|
||||||
|
+ report
|
||||||
|
)
|
||||||
|
# log.error(report)
|
||||||
|
log.debug(report)
|
||||||
|
|
||||||
|
else:
|
||||||
|
report = (
|
||||||
|
'Queueing OVERRUN msg on caller task:\n\n'
|
||||||
|
+ report
|
||||||
|
)
|
||||||
|
log.debug(report)
|
||||||
|
|
||||||
# XXX NOTE XXX
|
# XXX NOTE XXX
|
||||||
# overrun is the ONLY case where returning early is fine!
|
# overrun is the ONLY case where returning early is fine!
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -609,6 +609,7 @@ class RemoteActorError(Exception):
|
||||||
# just after <Type(
|
# just after <Type(
|
||||||
# |___ ..
|
# |___ ..
|
||||||
tb_body_indent=1,
|
tb_body_indent=1,
|
||||||
|
boxer_header=self.relay_uid,
|
||||||
)
|
)
|
||||||
|
|
||||||
tail = ''
|
tail = ''
|
||||||
|
|
|
@ -95,6 +95,10 @@ async def open_root_actor(
|
||||||
|
|
||||||
hide_tb: bool = True,
|
hide_tb: bool = True,
|
||||||
|
|
||||||
|
# TODO, a way for actors to augment passing derived
|
||||||
|
# read-only state to sublayers?
|
||||||
|
# extra_rt_vars: dict|None = None,
|
||||||
|
|
||||||
) -> Actor:
|
) -> Actor:
|
||||||
'''
|
'''
|
||||||
Runtime init entry point for ``tractor``.
|
Runtime init entry point for ``tractor``.
|
||||||
|
|
|
@ -456,11 +456,14 @@ class Actor:
|
||||||
)
|
)
|
||||||
|
|
||||||
if _pre_chan:
|
if _pre_chan:
|
||||||
log.warning(
|
|
||||||
# con_status += (
|
# con_status += (
|
||||||
# ^TODO^ swap once we minimize conn duplication
|
# ^TODO^ swap once we minimize conn duplication
|
||||||
f' -> Wait, we already have IPC with `{uid_short}`??\n'
|
# -[ ] last thing might be reg/unreg runtime reqs?
|
||||||
f' |_{_pre_chan}\n'
|
# log.warning(
|
||||||
|
log.debug(
|
||||||
|
f'?Wait?\n'
|
||||||
|
f'We already have IPC with peer {uid_short!r}\n'
|
||||||
|
f'|_{_pre_chan}\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
# IPC connection tracking for both peers and new children:
|
# IPC connection tracking for both peers and new children:
|
||||||
|
|
|
@ -1420,6 +1420,10 @@ def any_connected_locker_child() -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
_ctlc_ignore_header: str = (
|
||||||
|
'Ignoring SIGINT while debug REPL in use'
|
||||||
|
)
|
||||||
|
|
||||||
def sigint_shield(
|
def sigint_shield(
|
||||||
signum: int,
|
signum: int,
|
||||||
frame: 'frame', # type: ignore # noqa
|
frame: 'frame', # type: ignore # noqa
|
||||||
|
@ -1501,7 +1505,9 @@ def sigint_shield(
|
||||||
# NOTE: don't emit this with `.pdb()` level in
|
# NOTE: don't emit this with `.pdb()` level in
|
||||||
# root without a higher level.
|
# root without a higher level.
|
||||||
log.runtime(
|
log.runtime(
|
||||||
f'Ignoring SIGINT while debug REPL in use by child '
|
_ctlc_ignore_header
|
||||||
|
+
|
||||||
|
f' by child '
|
||||||
f'{uid_in_debug}\n'
|
f'{uid_in_debug}\n'
|
||||||
)
|
)
|
||||||
problem = None
|
problem = None
|
||||||
|
@ -1535,7 +1541,9 @@ def sigint_shield(
|
||||||
# NOTE: since we emit this msg on ctl-c, we should
|
# NOTE: since we emit this msg on ctl-c, we should
|
||||||
# also always re-print the prompt the tail block!
|
# also always re-print the prompt the tail block!
|
||||||
log.pdb(
|
log.pdb(
|
||||||
'Ignoring SIGINT while pdb REPL in use by root actor..\n'
|
_ctlc_ignore_header
|
||||||
|
+
|
||||||
|
f' by root actor..\n'
|
||||||
f'{DebugStatus.repl_task}\n'
|
f'{DebugStatus.repl_task}\n'
|
||||||
f' |_{repl}\n'
|
f' |_{repl}\n'
|
||||||
)
|
)
|
||||||
|
@ -1596,16 +1604,20 @@ def sigint_shield(
|
||||||
repl
|
repl
|
||||||
):
|
):
|
||||||
log.pdb(
|
log.pdb(
|
||||||
f'Ignoring SIGINT while local task using debug REPL\n'
|
_ctlc_ignore_header
|
||||||
f'|_{repl_task}\n'
|
+
|
||||||
f' |_{repl}\n'
|
f' by local task\n\n'
|
||||||
|
f'{repl_task}\n'
|
||||||
|
f' |_{repl}\n'
|
||||||
)
|
)
|
||||||
elif req_task:
|
elif req_task:
|
||||||
log.debug(
|
log.debug(
|
||||||
'Ignoring SIGINT while debug request task is open but either,\n'
|
_ctlc_ignore_header
|
||||||
'- someone else is already REPL-in and has the `Lock`, or\n'
|
+
|
||||||
'- some other local task already is replin?\n'
|
f' by local request-task and either,\n'
|
||||||
f'|_{req_task}\n'
|
f'- someone else is already REPL-in and has the `Lock`, or\n'
|
||||||
|
f'- some other local task already is replin?\n\n'
|
||||||
|
f'{req_task}\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO can we remove this now?
|
# TODO can we remove this now?
|
||||||
|
|
|
@ -234,7 +234,7 @@ def find_caller_info(
|
||||||
_frame2callerinfo_cache: dict[FrameType, CallerInfo] = {}
|
_frame2callerinfo_cache: dict[FrameType, CallerInfo] = {}
|
||||||
|
|
||||||
|
|
||||||
# TODO: -[x] move all this into new `.devx._code`!
|
# TODO: -[x] move all this into new `.devx._frame_stack`!
|
||||||
# -[ ] consider rename to _callstack?
|
# -[ ] consider rename to _callstack?
|
||||||
# -[ ] prolly create a `@runtime_api` dec?
|
# -[ ] prolly create a `@runtime_api` dec?
|
||||||
# |_ @api_frame seems better?
|
# |_ @api_frame seems better?
|
||||||
|
@ -286,3 +286,18 @@ def api_frame(
|
||||||
wrapped._call_infos: dict[FrameType, CallerInfo] = _frame2callerinfo_cache
|
wrapped._call_infos: dict[FrameType, CallerInfo] = _frame2callerinfo_cache
|
||||||
wrapped.__api_func__: bool = True
|
wrapped.__api_func__: bool = True
|
||||||
return wrapper(wrapped)
|
return wrapper(wrapped)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: something like this instead of the adhoc frame-unhiding
|
||||||
|
# blocks all over the runtime!! XD
|
||||||
|
# -[ ] ideally we can expect a certain error (set) and if something
|
||||||
|
# else is raised then all frames below the wrapped one will be
|
||||||
|
# un-hidden via `__tracebackhide__: bool = False`.
|
||||||
|
# |_ might need to dynamically mutate the code objs like
|
||||||
|
# `pdbp.hideframe()` does?
|
||||||
|
# -[ ] use this as a `@acm` decorator as introed in 3.10?
|
||||||
|
# @acm
|
||||||
|
# async def unhide_frame_when_not(
|
||||||
|
# error_set: set[BaseException],
|
||||||
|
# ) -> TracebackType:
|
||||||
|
# ...
|
||||||
|
|
|
@ -53,6 +53,7 @@ def pformat_boxed_tb(
|
||||||
|
|
||||||
tb_box_indent: int|None = None,
|
tb_box_indent: int|None = None,
|
||||||
tb_body_indent: int = 1,
|
tb_body_indent: int = 1,
|
||||||
|
boxer_header: str = '-'
|
||||||
|
|
||||||
) -> str:
|
) -> str:
|
||||||
'''
|
'''
|
||||||
|
@ -88,9 +89,9 @@ def pformat_boxed_tb(
|
||||||
|
|
||||||
tb_box: str = (
|
tb_box: str = (
|
||||||
f'|\n'
|
f'|\n'
|
||||||
f' ------ - ------\n'
|
f' ------ {boxer_header} ------\n'
|
||||||
f'{tb_body}'
|
f'{tb_body}'
|
||||||
f' ------ - ------\n'
|
f' ------ {boxer_header}- ------\n'
|
||||||
f'_|\n'
|
f'_|\n'
|
||||||
)
|
)
|
||||||
tb_box_indent: str = (
|
tb_box_indent: str = (
|
||||||
|
|
|
@ -41,8 +41,10 @@ import textwrap
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
Callable,
|
||||||
|
Protocol,
|
||||||
Type,
|
Type,
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
@ -181,7 +183,11 @@ def mk_dec(
|
||||||
dec_hook: Callable|None = None,
|
dec_hook: Callable|None = None,
|
||||||
|
|
||||||
) -> MsgDec:
|
) -> MsgDec:
|
||||||
|
'''
|
||||||
|
Create an IPC msg decoder, normally used as the
|
||||||
|
`PayloadMsg.pld: PayloadT` field decoder inside a `PldRx`.
|
||||||
|
|
||||||
|
'''
|
||||||
return MsgDec(
|
return MsgDec(
|
||||||
_dec=msgpack.Decoder(
|
_dec=msgpack.Decoder(
|
||||||
type=spec, # like `MsgType[Any]`
|
type=spec, # like `MsgType[Any]`
|
||||||
|
@ -227,6 +233,13 @@ def pformat_msgspec(
|
||||||
join_char: str = '\n',
|
join_char: str = '\n',
|
||||||
|
|
||||||
) -> str:
|
) -> str:
|
||||||
|
'''
|
||||||
|
Pretty `str` format the `msgspec.msgpack.Decoder.type` attribute
|
||||||
|
for display in (console) log messages as a nice (maybe multiline)
|
||||||
|
presentation of all supported `Struct`s (subtypes) available for
|
||||||
|
typed decoding.
|
||||||
|
|
||||||
|
'''
|
||||||
dec: msgpack.Decoder = getattr(codec, 'dec', codec)
|
dec: msgpack.Decoder = getattr(codec, 'dec', codec)
|
||||||
return join_char.join(
|
return join_char.join(
|
||||||
mk_msgspec_table(
|
mk_msgspec_table(
|
||||||
|
@ -630,31 +643,57 @@ def limit_msg_spec(
|
||||||
# # import pdbp; pdbp.set_trace()
|
# # import pdbp; pdbp.set_trace()
|
||||||
# assert ext_codec.pld_spec == extended_spec
|
# assert ext_codec.pld_spec == extended_spec
|
||||||
# yield ext_codec
|
# yield ext_codec
|
||||||
|
#
|
||||||
|
# ^-TODO-^ is it impossible to make something like this orr!?
|
||||||
|
|
||||||
|
# TODO: make an auto-custom hook generator from a set of input custom
|
||||||
|
# types?
|
||||||
|
# -[ ] below is a proto design using a `TypeCodec` idea?
|
||||||
|
#
|
||||||
|
# type var for the expected interchange-lib's
|
||||||
|
# IPC-transport type when not available as a built-in
|
||||||
|
# serialization output.
|
||||||
|
WireT = TypeVar('WireT')
|
||||||
|
|
||||||
|
|
||||||
# TODO: make something similar to this inside `._codec` such that
|
# TODO: some kinda (decorator) API for built-in subtypes
|
||||||
# user can just pass a type table of some sort?
|
# that builds this implicitly by inspecting the `mro()`?
|
||||||
# -[ ] we would need to decode all msgs to `pretty_struct.Struct`
|
class TypeCodec(Protocol):
|
||||||
# and then call `.to_dict()` on them?
|
'''
|
||||||
# -[x] we're going to need to re-impl all the stuff changed in the
|
A per-custom-type wire-transport serialization translator
|
||||||
# runtime port such that it can handle dicts or `Msg`s?
|
description type.
|
||||||
#
|
|
||||||
# def mk_dict_msg_codec_hooks() -> tuple[Callable, Callable]:
|
'''
|
||||||
# '''
|
src_type: Type
|
||||||
# Deliver a `enc_hook()`/`dec_hook()` pair which does
|
wire_type: WireT
|
||||||
# manual convertion from our above native `Msg` set
|
|
||||||
# to `dict` equivalent (wire msgs) in order to keep legacy compat
|
def encode(obj: Type) -> WireT:
|
||||||
# with the original runtime implementation.
|
...
|
||||||
#
|
|
||||||
# Note: this is is/was primarly used while moving the core
|
def decode(
|
||||||
# runtime over to using native `Msg`-struct types wherein we
|
obj_type: Type[WireT],
|
||||||
# start with the send side emitting without loading
|
obj: WireT,
|
||||||
# a typed-decoder and then later flipping the switch over to
|
) -> Type:
|
||||||
# load to the native struct types once all runtime usage has
|
...
|
||||||
# been adjusted appropriately.
|
|
||||||
#
|
|
||||||
# '''
|
class MsgpackTypeCodec(TypeCodec):
|
||||||
# return (
|
...
|
||||||
# # enc_to_dict,
|
|
||||||
# dec_from_dict,
|
|
||||||
# )
|
def mk_codec_hooks(
|
||||||
|
type_codecs: list[TypeCodec],
|
||||||
|
|
||||||
|
) -> tuple[Callable, Callable]:
|
||||||
|
'''
|
||||||
|
Deliver a `enc_hook()`/`dec_hook()` pair which handle
|
||||||
|
manual convertion from an input `Type` set such that whenever
|
||||||
|
the `TypeCodec.filter()` predicate matches the
|
||||||
|
`TypeCodec.decode()` is called on the input native object by
|
||||||
|
the `dec_hook()` and whenever the
|
||||||
|
`isiinstance(obj, TypeCodec.type)` matches against an
|
||||||
|
`enc_hook(obj=obj)` the return value is taken from a
|
||||||
|
`TypeCodec.encode(obj)` callback.
|
||||||
|
|
||||||
|
'''
|
||||||
|
...
|
||||||
|
|
|
@ -30,9 +30,9 @@ from msgspec import (
|
||||||
Struct as _Struct,
|
Struct as _Struct,
|
||||||
structs,
|
structs,
|
||||||
)
|
)
|
||||||
from pprint import (
|
# from pprint import (
|
||||||
saferepr,
|
# saferepr,
|
||||||
)
|
# )
|
||||||
|
|
||||||
from tractor.log import get_logger
|
from tractor.log import get_logger
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@ class DiffDump(UserList):
|
||||||
for k, left, right in self:
|
for k, left, right in self:
|
||||||
repstr += (
|
repstr += (
|
||||||
f'({k},\n'
|
f'({k},\n'
|
||||||
f'\t{repr(left)},\n'
|
f' |_{repr(left)},\n'
|
||||||
f'\t{repr(right)},\n'
|
f' |_{repr(right)},\n'
|
||||||
')\n'
|
')\n'
|
||||||
)
|
)
|
||||||
repstr += ']\n'
|
repstr += ']\n'
|
||||||
|
@ -144,15 +144,22 @@ def pformat(
|
||||||
field_indent=indent + field_indent,
|
field_indent=indent + field_indent,
|
||||||
)
|
)
|
||||||
|
|
||||||
else: # the `pprint` recursion-safe format:
|
else:
|
||||||
|
val_str: str = repr(v)
|
||||||
|
|
||||||
|
# XXX LOL, below just seems to be f#$%in causing
|
||||||
|
# recursion errs..
|
||||||
|
#
|
||||||
|
# the `pprint` recursion-safe format:
|
||||||
# https://docs.python.org/3.11/library/pprint.html#pprint.saferepr
|
# https://docs.python.org/3.11/library/pprint.html#pprint.saferepr
|
||||||
try:
|
# try:
|
||||||
val_str: str = saferepr(v)
|
# val_str: str = saferepr(v)
|
||||||
except Exception:
|
# except Exception:
|
||||||
log.exception(
|
# log.exception(
|
||||||
'Failed to `saferepr({type(struct)})` !?\n'
|
# 'Failed to `saferepr({type(struct)})` !?\n'
|
||||||
)
|
# )
|
||||||
return _Struct.__repr__(struct)
|
# raise
|
||||||
|
# return _Struct.__repr__(struct)
|
||||||
|
|
||||||
# TODO: LOLOL use `textwrap.indent()` instead dawwwwwg!
|
# TODO: LOLOL use `textwrap.indent()` instead dawwwwwg!
|
||||||
obj_str += (field_ws + f'{k}: {typ_name} = {val_str},\n')
|
obj_str += (field_ws + f'{k}: {typ_name} = {val_str},\n')
|
||||||
|
@ -203,12 +210,7 @@ class Struct(
|
||||||
return sin_props
|
return sin_props
|
||||||
|
|
||||||
pformat = pformat
|
pformat = pformat
|
||||||
# __repr__ = pformat
|
|
||||||
# __str__ = __repr__ = pformat
|
|
||||||
# TODO: use a pprint.PrettyPrinter instance around ONLY rendering
|
|
||||||
# inside a known tty?
|
|
||||||
# def __repr__(self) -> str:
|
|
||||||
# ...
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
try:
|
try:
|
||||||
return pformat(self)
|
return pformat(self)
|
||||||
|
@ -218,6 +220,13 @@ class Struct(
|
||||||
)
|
)
|
||||||
return _Struct.__repr__(self)
|
return _Struct.__repr__(self)
|
||||||
|
|
||||||
|
# __repr__ = pformat
|
||||||
|
# __str__ = __repr__ = pformat
|
||||||
|
# TODO: use a pprint.PrettyPrinter instance around ONLY rendering
|
||||||
|
# inside a known tty?
|
||||||
|
# def __repr__(self) -> str:
|
||||||
|
# ...
|
||||||
|
|
||||||
def copy(
|
def copy(
|
||||||
self,
|
self,
|
||||||
update: dict | None = None,
|
update: dict | None = None,
|
||||||
|
@ -267,13 +276,15 @@ class Struct(
|
||||||
fi.type(getattr(self, fi.name)),
|
fi.type(getattr(self, fi.name)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: make a mod func instead and just point to it here for
|
||||||
|
# method impl?
|
||||||
def __sub__(
|
def __sub__(
|
||||||
self,
|
self,
|
||||||
other: Struct,
|
other: Struct,
|
||||||
|
|
||||||
) -> DiffDump[tuple[str, Any, Any]]:
|
) -> DiffDump[tuple[str, Any, Any]]:
|
||||||
'''
|
'''
|
||||||
Compare fields/items key-wise and return a ``DiffDump``
|
Compare fields/items key-wise and return a `DiffDump`
|
||||||
for easy visual REPL comparison B)
|
for easy visual REPL comparison B)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -290,3 +301,42 @@ class Struct(
|
||||||
))
|
))
|
||||||
|
|
||||||
return diffs
|
return diffs
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fields_diff(
|
||||||
|
cls,
|
||||||
|
other: dict|Struct,
|
||||||
|
|
||||||
|
) -> DiffDump[tuple[str, Any, Any]]:
|
||||||
|
'''
|
||||||
|
Very similar to `PrettyStruct.__sub__()` except accepts an
|
||||||
|
input `other: dict` (presumably that would normally be called
|
||||||
|
like `Struct(**other)`) which returns a `DiffDump` of the
|
||||||
|
fields of the struct and the `dict`'s fields.
|
||||||
|
|
||||||
|
'''
|
||||||
|
nullish = object()
|
||||||
|
consumed: dict = other.copy()
|
||||||
|
diffs: DiffDump[tuple[str, Any, Any]] = DiffDump()
|
||||||
|
for fi in structs.fields(cls):
|
||||||
|
field_name: str = fi.name
|
||||||
|
# ours: Any = getattr(self, field_name)
|
||||||
|
theirs: Any = consumed.pop(field_name, nullish)
|
||||||
|
if theirs is nullish:
|
||||||
|
diffs.append((
|
||||||
|
field_name,
|
||||||
|
f'{fi.type!r}',
|
||||||
|
'NOT-DEFINED in `other: dict`',
|
||||||
|
))
|
||||||
|
|
||||||
|
# when there are lingering fields in `other` that this struct
|
||||||
|
# DOES NOT define we also append those.
|
||||||
|
if consumed:
|
||||||
|
for k, v in consumed.items():
|
||||||
|
diffs.append((
|
||||||
|
k,
|
||||||
|
f'NOT-DEFINED for `{cls.__name__}`',
|
||||||
|
f'`other: dict` has value = {v!r}',
|
||||||
|
))
|
||||||
|
|
||||||
|
return diffs
|
||||||
|
|
|
@ -245,14 +245,14 @@ def _run_asyncio_task(
|
||||||
result != orig and
|
result != orig and
|
||||||
aio_err is None and
|
aio_err is None and
|
||||||
|
|
||||||
# in the ``open_channel_from()`` case we don't
|
# in the `open_channel_from()` case we don't
|
||||||
# relay through the "return value".
|
# relay through the "return value".
|
||||||
not provide_channels
|
not provide_channels
|
||||||
):
|
):
|
||||||
to_trio.send_nowait(result)
|
to_trio.send_nowait(result)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# if the task was spawned using ``open_channel_from()``
|
# if the task was spawned using `open_channel_from()`
|
||||||
# then we close the channels on exit.
|
# then we close the channels on exit.
|
||||||
if provide_channels:
|
if provide_channels:
|
||||||
# only close the sender side which will relay
|
# only close the sender side which will relay
|
||||||
|
@ -500,7 +500,7 @@ async def run_task(
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# simple async func
|
# simple async func
|
||||||
chan = _run_asyncio_task(
|
chan: LinkedTaskChannel = _run_asyncio_task(
|
||||||
func,
|
func,
|
||||||
qsize=1,
|
qsize=1,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
@ -530,7 +530,7 @@ async def open_channel_from(
|
||||||
spawned ``asyncio`` task and ``trio``.
|
spawned ``asyncio`` task and ``trio``.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
chan = _run_asyncio_task(
|
chan: LinkedTaskChannel = _run_asyncio_task(
|
||||||
target,
|
target,
|
||||||
qsize=2**8,
|
qsize=2**8,
|
||||||
provide_channels=True,
|
provide_channels=True,
|
||||||
|
|
|
@ -382,7 +382,7 @@ class BroadcastReceiver(ReceiveChannel):
|
||||||
# likely it makes sense to unwind back to the
|
# likely it makes sense to unwind back to the
|
||||||
# underlying?
|
# underlying?
|
||||||
# import tractor
|
# import tractor
|
||||||
# await tractor.breakpoint()
|
# await tractor.pause()
|
||||||
log.warning(
|
log.warning(
|
||||||
f'Only one sub left for {self}?\n'
|
f'Only one sub left for {self}?\n'
|
||||||
'We can probably unwind from breceiver?'
|
'We can probably unwind from breceiver?'
|
||||||
|
|
Loading…
Reference in New Issue