Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multihomed transport (server) addrs 🕶️ #367

Draft
wants to merge 65 commits into
base: asyncio_debugger_support
Choose a base branch
from

Commits on Sep 27, 2023

  1. Mk gather_contexts() support @acms yielding None

    We were using a `all(<yielded values>)` condition which obviously won't
    work if the batched managers yield any non-truthy value. So instead see
    the `unwrapped: dict` with the `id(mngrs)` and only unblock once all
    values have been filled in to be something that is not that value.
    goodboy committed Sep 27, 2023
    Configuration menu
    Copy the full SHA
    ee151b0 View commit details
    Browse the repository at this point in the history
  2. Init-support for "multi homed" transports

    Since we'd like to eventually allow a diverse set of transport
    (protocol) methods and stacks, and a multi-peer discovery system for
    distributed actor-tree applications, this reworks all runtime internals
    to support multi-homing for any given tree on a logical host. In other
    words any actor can now bind its transport server (currently only
    unsecured TCP + `msgspec`) to more then one address available in its
    (linux) network namespace. Further, registry actors (now dubbed
    "registars" instead of "arbiters") can also similarly bind to multiple
    network addresses and provide discovery services to remote actors via
    multiple addresses which can now be provided at runtime startup.
    
    Deats:
    - adjust `._runtime` internals to use a `list[tuple[str, int]]` (and
      thus pluralized) socket address sequence where applicable for transport
      server socket binds, now exposed via `Actor.accept_addrs`:
      - `Actor.__init__()` now takes a `registry_addrs: list`.
      - `Actor.is_arbiter` -> `.is_registrar`.
      - `._arb_addr` -> `._reg_addrs: list[tuple]`.
      - always reg and de-reg from all registrars in `async_main()`.
      - only set the global runtime var `'_root_mailbox'` to the loopback
        address since normally all in-tree processes should have access to
        it, right?
      - `._serve_forever()` task now takes `listen_sockaddrs: list[tuple]`
    - make `open_root_actor()` take a `registry_addrs: list[tuple[str, int]]`
      and defaults when not passed.
    - change `ActorNursery.start_..()` methods take `bind_addrs: list` and
      pass down through the spawning layer(s) via the parent-seed-msg.
    - generalize all `._discovery()` APIs to accept `registry_addrs`-like
      inputs and move all relevant subsystems to adopt the "registry" style
      naming instead of "arbiter":
      - make `find_actor()` support batched concurrent portal queries over
        all provided input addresses using `.trionics.gather_contexts()` Bo
      - syntax: move to using `async with <tuples>` 3.9+ style chained
        @acms.
      - a general modernization of the code to a python 3.9+ style.
      - start deprecation and change to "registry" naming / semantics:
        - `._discovery.get_arbiter()` -> `.get_registry()`
    goodboy committed Sep 27, 2023
    Configuration menu
    Copy the full SHA
    3d0e955 View commit details
    Browse the repository at this point in the history

Commits on Sep 28, 2023

  1. Kick off .devx subpkg for our dev tools B)

    Where `.devx` is "developer experience", a hopefully broad enough subpkg
    name for all the slick stuff planned to augment working on the actor
    runtime 💥
    
    Move the `._debug` module into the new subpkg and adjust rest of core
    code base to reflect import path change. Also add a new
    `.devx._debug.open_crash_handler()` manager for wrapping any sync code
    outside a `trio.run()` which is handy for eventual CLI addons for
    popular frameworks like `click`/`typer`.
    goodboy committed Sep 28, 2023
    Configuration menu
    Copy the full SHA
    fa9a9cf View commit details
    Browse the repository at this point in the history
  2. Start .devx.cli extensions for pop CLI frameworks

    Starting of with just a `typer` (and thus transitively `click`)
    `typer.Typer.callback` hook which allows passthrough of the `--ll
    <loglevel: str>` and `--pdb <debug_mode: bool>` flags for use when
    building CLIs that use the runtime Bo
    
    Still needs lotsa refinement and obviously better docs but, the doc
    string for `load_runtime_vars()` shows how to use the underlying
    `.devx._debug.open_crash_handler()` via a wrapper that can be passed the
    `--pdb` flag and then enable debug mode throughout the entire actor
    system.
    goodboy committed Sep 28, 2023
    Configuration menu
    Copy the full SHA
    7bed470 View commit details
    Browse the repository at this point in the history

Commits on Sep 29, 2023

  1. Add libp2p style "multi-address" parser from piker

    Details are in the module docs; this is a first draft with lotsa room
    for refinement and extension.
    goodboy committed Sep 29, 2023
    Configuration menu
    Copy the full SHA
    de89e3a View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    86da79a View commit details
    Browse the repository at this point in the history

Commits on Oct 2, 2023

  1. Configuration menu
    Copy the full SHA
    e94f126 View commit details
    Browse the repository at this point in the history

Commits on Oct 3, 2023

  1. Configuration menu
    Copy the full SHA
    4314a59 View commit details
    Browse the repository at this point in the history

Commits on Oct 6, 2023

  1. Start inter-peer cancellation test mod

    Move over relevant test from the "context semantics" test module which
    was already verifying peer-caused-`ContextCancelled.canceller: tuple`
    error info and propagation during an inter-peer cancellation scenario.
    
    Also begin a more general set of inter-peer cancellation tests starting
    with the simplest case where when a peer is cancelled the parent should
    NOT get an "muted" `trio.Cancelled` and instead
    a `tractor.ContextCancelled` with a `.canceller: tuple` which points to
    the sibling actor which requested the peer cancel.
    goodboy committed Oct 6, 2023
    Configuration menu
    Copy the full SHA
    78c0d2b View commit details
    Browse the repository at this point in the history
  2. Add shielding support to .pause()

    Implement it like you'd expect using simply a wrapping
    `trio.CancelScope` which is itself shielded by the input `shield: bool`
    B)
    
    There's seemingly still some issues with the frame selection when the
    REPL engages and not sure how to resolve it yet but at least this does
    indeed work for practical purposes. Still needs a test obviously!
    goodboy committed Oct 6, 2023
    Configuration menu
    Copy the full SHA
    18a1634 View commit details
    Browse the repository at this point in the history

Commits on Oct 7, 2023

  1. Configuration menu
    Copy the full SHA
    d24a9e1 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    c4cd573 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    a09b856 View commit details
    Browse the repository at this point in the history

Commits on Oct 8, 2023

  1. Configuration menu
    Copy the full SHA
    919e462 View commit details
    Browse the repository at this point in the history

Commits on Oct 10, 2023

  1. Always raise remote (cancelled) error if set

    Previously we weren't raising a remote error if the local scope was
    cancelled during a call to `Context.result()` which is problematic if
    the caller WAS NOT the requester for said remote cancellation; in that
    case we still want a `ContextCancelled` raised with the `.canceller:
    str` set to the cancelling actor uid.
    
    Further fix a naming bug where the (seemingly older) `._remote_err` was
    being set to such an error instead of `._remote_error` XD
    goodboy committed Oct 10, 2023
    Configuration menu
    Copy the full SHA
    575a24a View commit details
    Browse the repository at this point in the history
  2. Comment all .pause(shield=True) attempts again, need to solve cance…

    …l scope `.__exit__()` frame hiding issue..
    goodboy committed Oct 10, 2023
    Configuration menu
    Copy the full SHA
    6d951c5 View commit details
    Browse the repository at this point in the history

Commits on Oct 16, 2023

  1. Factor non-yield stream msg processing into helper

    Since both `MsgStream.receive()` and `.receive_nowait()` need the same
    raising logic when a non-stream msg arrives (so that maybe an
    appropriate IPC translated error can be raised) move the `KeyError`
    handler code into a new `._streaming._raise_from_no_yield_msg()` func
    and call it from both methods to make the error-interface-raising
    symmetrical across both methods.
    goodboy committed Oct 16, 2023
    Configuration menu
    Copy the full SHA
    2fdb8fc View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    07cec02 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    ae326cb View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    ab2664d View commit details
    Browse the repository at this point in the history
  5. ._exceptions: typing and error unpacking updates

    Bump type annotations to 3.10+ style throughout module as well as fill
    out doc strings a bit. Inside `unpack_error()` pop any `error_dict: dict`
    and,
    - return `None` early if not found,
    - versus pass directly as `**error_dict` to the error constructor
      instead of a double field read.
    goodboy committed Oct 16, 2023
    Configuration menu
    Copy the full SHA
    e4a6223 View commit details
    Browse the repository at this point in the history

Commits on Oct 17, 2023

  1. Drop msg kwarg from Context.cancel()

    Well first off, turns out it's never used and generally speaking
    doesn't seem to help much with "runtime hacking/debugging"; why would
    we need to "fabricate" a msg when `.cancel()` is called to self-cancel?
    
    Also (and since `._maybe_cancel_and_set_remote_error()` now takes an
    `error: BaseException` as input and thus expects error-msg unpacking
    prior to being called), we now manually set `Context._cancel_msg: dict`
    just prior to any remote error assignment - so any case where we would
    have fabbed a "cancel msg" near calling `.cancel()`, just do the manual
    assign.
    
    In this vein some other subtle changes:
    - obviously don't set `._cancel_msg` in `.cancel()` since it's no longer
      an input.
    - generally do walrus-style `error := unpack_error()` before applying
      and setting remote error-msg state.
    - always raise any `._remote_error` in `.result()` instead of returning
      the exception instance and check before AND after the underlying mem
      chan read.
    - add notes/todos around `raise self._remote_error from None` masking of
      (runtime) errors in `._maybe_raise_remote_err()` and use it inside
      `.result()` since we had the inverse duplicate logic there anyway..
    
    Further, this adds and extends a ton of (internal) interface docs and
    details comments around the `Context` API including many subtleties
    pertaining to calling `._maybe_cancel_and_set_remote_error()`.
    goodboy committed Oct 17, 2023
    Configuration menu
    Copy the full SHA
    534e5d1 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    7eb31f3 View commit details
    Browse the repository at this point in the history

Commits on Oct 18, 2023

  1. Get mega-pedantic in Portal.open_context()

    Specifically in the `.__aexit__()` phase to ensure remote,
    runtime-internal, and locally raised error-during-cancelled-handling
    exceptions are NEVER masked by a local `ContextCancelled` or any
    exception group of `trio.Cancelled`s.
    
    Also adds a ton of details to doc strings including extreme detail
    surrounding the `ContextCancelled` raising cases and their processing
    inside `.open_context()`'s exception handler blocks.
    
    Details, details:
    - internal rename `err`/`_err` stuff to just be `scope_err` since it's
      effectively the error bubbled up from the context's surrounding (and
      cross-actor) "scope".
    - always shield `._recv_chan.aclose()` to avoid any `Cancelled` from
      masking the `scope_err` with a runtime related `trio.Cancelled`.
    - explicitly catch the specific set of `scope_err: BaseException` that
      we can reasonably expect to handle instead of the catch-all parent
      type including exception groups, cancels and KBIs.
    goodboy committed Oct 18, 2023
    Configuration menu
    Copy the full SHA
    63b1488 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    43b659d View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    87c1113 View commit details
    Browse the repository at this point in the history
  4. Add a first serious inter-peer remote cancel suite

    Tests that appropriate `Context` exit state, the relay of
    a `ContextCancelled` error and its `.canceller: tuple[str, str]` value
    are set when an inter-peer cancellation happens via an "out of band"
    request method (in this case using `Portal.cancel_actor()` and that
    cancellation is propagated "horizontally" to other peers. Verify that
    any such cancellation scenario which also experiences an "error during
    `ContextCancelled` handling" DOES NOT result in that further error being
    suppressed and that the user's exception bubbles out of the
    `Context.open_context()` block(s) appropriately!
    
    Likely more tests to come as well as some factoring of the teardown
    state checks where possible.
    
    Pertains to serious testing the major work landing in #357
    goodboy committed Oct 18, 2023
    Configuration menu
    Copy the full SHA
    ca3f7a1 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    fcc8cee View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    215fec1 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    0c74b04 View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    190845c View commit details
    Browse the repository at this point in the history
  9. Rename fixture arb_addr -> reg_addr and set the session value glo…

    …bally as `._root._default_lo_addrs`
    goodboy committed Oct 18, 2023
    Configuration menu
    Copy the full SHA
    1e689ee View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    6b1ceee View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    0e94572 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    022bf8c View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    2e81ccf View commit details
    Browse the repository at this point in the history
  14. Configuration menu
    Copy the full SHA
    42d621b View commit details
    Browse the repository at this point in the history

Commits on Oct 19, 2023

  1. Get remaining suites passing..

    ..by ensuring `reg_addr` fixture value passthrough to subactor eps
    goodboy committed Oct 19, 2023
    Configuration menu
    Copy the full SHA
    a3ed30e View commit details
    Browse the repository at this point in the history
  2. Expose per-actor registry addrs via .reg_addrs

    Since it's handy to be able to debug the *writing* of this instance var
    (particularly when checking state passed down to a child in
    `Actor._from_parent()`), rename and wrap the underlying
    `Actor._reg_addrs` as a settable `@property` and add validation to
    the `.setter` for sanity - actor discovery is a critical functionality.
    
    Other tweaks:
    - fix `.cancel_soon()` to pass expected argument..
    - update internal runtime error message to be simpler and link to GH issues.
    - use new `Actor.reg_addrs` throughout core.
    goodboy committed Oct 19, 2023
    Configuration menu
    Copy the full SHA
    1d6f555 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    9da3b63 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    2f0bed3 View commit details
    Browse the repository at this point in the history

Commits on Oct 23, 2023

  1. Configuration menu
    Copy the full SHA
    0518b3a View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    5a94e8f View commit details
    Browse the repository at this point in the history
  3. Be mega-pedantic with ContextCancelled semantics

    As part of extremely detailed inter-peer-actor testing, add much more
    granular `Context` cancellation state tracking via the following (new)
    fields:
    - `.canceller: tuple[str, str]` the uuid of the actor responsible for
      the cancellation condition - always set by
      `Context._maybe_cancel_and_set_remote_error()` and replaces
      `._cancelled_remote` and `.cancel_called_remote`. If set, this value
      should normally always match a value from some `ContextCancelled`
      raised or caught by one side of the context.
    - `._local_error` which is always set to the locally raised (and caller
      or callee task's scope-internal) error which caused any
      eventual cancellation/error condition and thus any closure of the
      context's per-task-side-`trio.Nursery`.
    - `.cancelled_caught: bool` is now always `True` whenever the local task
      catches (or "silently absorbs") a `ContextCancelled` (a `ctxc`) that
      indeed originated from one of the context's linked tasks or any other
      context which raised its own `ctxc` in the current `.open_context()` scope.
      => whenever there is a case that no `ContextCancelled` was raised
      **in** the `.open_context().__aexit__()` (eg. `ctx.result()` called
      after a call `ctx.cancel()`), we still consider the context's as
      having "caught a cancellation" since the `ctxc` was indeed silently
      handled by the cancel requester; all other error cases are already
      represented by mirroring the state of the `._scope: trio.CancelScope`
      => IOW there should be **no case** where an error is **not raised** in
      the context's scope and `.cancelled_caught: bool == False`, i.e. no
      case where `._scope.cancelled_caught == False and ._local_error is not
      None`!
    - always raise any `ctxc` from `.open_stream()` if `._cancel_called ==
      True` - if the cancellation request has not already resulted in
      a `._remote_error: ContextCancelled` we raise a `RuntimeError` to
      indicate improper usage to the guilty side's task code.
    - make `._maybe_raise_remote_err()` a sync func and don't raise
      any `ctxc` which is matched against a `.canceller` determined to
      be the current actor, aka a "self cancel", and always set the
      `._local_error` to any such `ctxc`.
    - `.side: str` taken from inside `.cancel()` and unused as of now since
      it might be better re-written as a similar `.is_opener() -> bool`?
    - drop unused `._started_received: bool`..
    - TONS and TONS of detailed comments/docs to attempt to explain all the
      possible cancellation/exit cases and how they should exhibit as either
      silent closes or raises from the `Context` API!
    
    Adjust the `._runtime._invoke()` code to match:
    - use `ctx._maybe_raise_remote_err()` in `._invoke()`.
    - adjust to new `.canceller` property.
    - more type hints.
    - better `log.cancel()` msging around self-cancels vs. peer-cancels.
    - always set the `._local_error: BaseException` for the "callee" task
      just like `Portal.open_context()` now will do B)
    
    Prior we were raising any `Context._remote_error` directly and doing
    (more or less) the same `ContextCancelled` "absorbing" logic (well
    kinda) in block; instead delegate to the method
    goodboy committed Oct 23, 2023
    Configuration menu
    Copy the full SHA
    131674e View commit details
    Browse the repository at this point in the history
  4. Be ultra-correct in Portal.open_context()

    This took way too long to get right but hopefully will give us grok-able
    and correct context exit semantics going forward B)
    
    The main fixes were:
    - always shielding the `MsgStream.aclose()` call on teardown to avoid
      bubbling a `Cancelled`.
    - properly absorbing any `ContextCancelled` in cases due to "self
      cancellation" using the new `Context.canceller` in the logic.
    - capturing any error raised by the `Context.result()` call in the
      "normal exit, result received" case and setting it as the
      `Context._local_error` so that self-cancels can be easily measured via
      `Context.cancelled_caught` in same way as remote-error caused
      cancellations.
    - extremely detailed comments around all of the cancellation-error cases
      to avoid ever getting confused about the control flow in the future XD
    goodboy committed Oct 23, 2023
    Configuration menu
    Copy the full SHA
    df31047 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    f4e6346 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    b77d123 View commit details
    Browse the repository at this point in the history
  7. Adjust test details where Context.cancel() is called

    We can now make asserts on `.cancelled_caught` and `_remote_error` vs.
    `_local_error`. Expect a runtime error when `Context.open_stream()` is
    called AFTER `.cancel()` and the remote `ContextCancelled` hasn't
    arrived (yet). Adjust to `'itself'` string in self-cancel case.
    goodboy committed Oct 23, 2023
    Configuration menu
    Copy the full SHA
    ecb525a View commit details
    Browse the repository at this point in the history
  8. Get inter-peer suite passing with all Context state checks!

    Definitely needs some cleaning and refinement but this gets us to stage
    1 of being pretty frickin correct i'd say 💃
    goodboy committed Oct 23, 2023
    Configuration menu
    Copy the full SHA
    ef0cfc4 View commit details
    Browse the repository at this point in the history

Commits on Oct 25, 2023

  1. Tons of interpeer test cleanup

    Drop all the nested `@acm` blocks and defunct comments from initial
    validations. Add some todos for cases that are still unclear such as
    whether the caller / streamer should have `.cancelled_caught == True` in
    it's teardown.
    goodboy committed Oct 25, 2023
    Configuration menu
    Copy the full SHA
    d651f3d View commit details
    Browse the repository at this point in the history

Commits on Nov 6, 2023

  1. Configuration menu
    Copy the full SHA
    227c9ea View commit details
    Browse the repository at this point in the history
  2. Fix doc string "its" typo..

    goodboy committed Nov 6, 2023
    Configuration menu
    Copy the full SHA
    48accbd View commit details
    Browse the repository at this point in the history

Commits on Nov 7, 2023

  1. Add open_root_actor(ensure_registry: bool)

    Allows forcing the opened actor to either obtain the passed registry
    addrs or raise a runtime error.
    goodboy committed Nov 7, 2023
    Configuration menu
    Copy the full SHA
    87cd725 View commit details
    Browse the repository at this point in the history

Commits on Dec 11, 2023

  1. Configuration menu
    Copy the full SHA
    3f15923 View commit details
    Browse the repository at this point in the history

Commits on Dec 12, 2023

  1. Configuration menu
    Copy the full SHA
    f415fc4 View commit details
    Browse the repository at this point in the history

Commits on Jan 2, 2024

  1. Guarding for IPC failures in ._runtime._invoke()

    Took me longer then i wanted to figure out the source of
    a failed-response to a remote-cancellation (in this case in `modden`
    where a client was cancelling a workspace layer.. but disconnects before
    receiving the ack msg) that was triggering an IPC error when sending the
    error msg for the cancellation of a `Actor._cancel_task()`, but since
    this (non-rpc) `._invoke()` task was trying to send to a now
    disconnected canceller it was resulting in a `BrokenPipeError` (or similar)
    error.
    
    Now, we except for such IPC errors and only raise them when,
    1. the transport `Channel` is for sure up (bc ow what's the point of
       trying to send an error on the thing that caused it..)
    2. it's definitely for handling an RPC task
    
    Similarly if the entire main invoke `try:` excepts,
    - we only hide the call-stack frame from the debugger (with
      `__tracebackhide__: bool`) if it's an RPC task that has a connected
      channel since we always want to see the frame when debugging internal
      task or IPC failures.
    - we don't bother trying to send errors to the context caller (actor)
      when it's a non-RPC request since failures on actor-runtime-internal
      tasks shouldn't really ever be reported remotely, only maybe raised
      locally.
    
    Also some other tidying,
    - this properly corrects for the self-cancel case where an RPC context
      is cancelled due to a local (runtime) task calling a method like
      `Actor.cancel_soon()`. We now set our own `.uid` as the
      `ContextCancelled.canceller` value so that other-end tasks know that
      the cancellation was due to a self-cancellation by the actor itself.
      We still need to properly test for this though!
    - add a more detailed module doc-str.
    - more explicit imports for `trio` core types throughout.
    goodboy committed Jan 2, 2024
    Configuration menu
    Copy the full SHA
    250275d View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    bea31f6 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    8143848 View commit details
    Browse the repository at this point in the history
  4. StackLevelAdapter._log(stacklevel: int) for custom levels..

    Apparently (and i don't know if this was always broken [i feel like no?]
    or is a recent change to stdlib's `logging` stuff) we need increment the
    `stacklevel` input by one for our custom level methods now? Without this
    you're going to see the path to the method's-callstack-frame on every
    emission instead of to the caller's. I first noticed this when debugging
    the workspace layer spawning in `modden.bigd` and then verified it in
    other depended projects..
    
    I guess we should add some tests for this as well XD
    goodboy committed Jan 2, 2024
    Configuration menu
    Copy the full SHA
    0002418 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    ce7b8a5 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    fdf3a1b View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    0bcdea2 View commit details
    Browse the repository at this point in the history
  8. Move missing-key-in-msg raiser to ._exceptions

    Since we use basically the exact same set of logic in
    `Portal.open_context()` when expecting the first `'started'` msg factor
    and generalize `._streaming._raise_from_no_yield_msg()` into a new
    `._exceptions._raise_from_no_key_in_msg()` (as per the lingering todo)
    which obvi requires a more generalized / optional signature including
    a caller specific `log` obj. Obvi call the new func from all the other
    modules X)
    goodboy committed Jan 2, 2024
    Configuration menu
    Copy the full SHA
    734bc09 View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    0294455 View commit details
    Browse the repository at this point in the history

Commits on Jan 4, 2024

  1. Configuration menu
    Copy the full SHA
    28ea8e7 View commit details
    Browse the repository at this point in the history