Updated ctx_cancel_semantics_and_overruns from github #11
Closed
goodboy
wants to merge 139 commits from
ctx_cancel_semantics_and_overruns into master
pull from: ctx_cancel_semantics_and_overruns
merge into: goodboy:master
goodboy:macos_fixed_2025
goodboy:macos_support
goodboy:piker_pin
goodboy:dereg_on_oserror
goodboy:pld_dec_refinements
goodboy:free_threading_prep
goodboy:oco_supervisor_prototype
goodboy:hilevel_serman
goodboy:multicast_revertable_streams
goodboy:ns_aware
goodboy:factor_into_hotbaud
goodboy:final_eg_refinements
goodboy:actor_cancelled_exc_type
goodboy:log_sys_testing
goodboy:main
goodboy:oob_cancel_testing
goodboy:cancelled_masking_guards
goodboy:strict_egs_everywhere
goodboy:POST_final_eg_refinements_failafter_investigation
goodboy:to_asyncio_eoc_signal
goodboy:enable_tpts
goodboy:repl_fixture
goodboy:SDOF_pre_sin_testing_XPSBACKUP
goodboy:cluster_api_egs_conflict
goodboy:moar_eg_smoothing
goodboy:pytest_pluginize
goodboy:structural_dynamics_of_flow
goodboy:one_ring_to_rule_them_all
goodboy:one_ring_to_rule_them_all_FROZEN_20250619
goodboy:auto_codecs
goodboy:leslies_extra_appendix
goodboy:shm_apis
goodboy:ext_type_plds
goodboy:py313_support
goodboy:aio_abandons
goodboy:sc_super_proto_dgrams
goodboy:runtime_to_msgspec
goodboy:pkg_tidying
goodboy:multihost_exs
goodboy:uv_migration_pre_msgspec_in_runtime
goodboy:remote_inceptions
goodboy:ext_type_plds_XPS_BACKUP
goodboy:modden_spawn_from_client_req
goodboy:multihomed
goodboy:devx_subpkg
goodboy:asyncio_debugger_support
goodboy:pre_pretty_struct_dep_commit_b54cb66
goodboy:ctx_cancel_semantics_and_overruns_REVERSED_FACEPALM
goodboy:uv_migration
goodboy:to_asyncio_refinery
goodboy:runtime_to_msgspec_XPS_BACKUP
goodboy:rae_message_packing
goodboy:msg_codecs
goodboy:old_msg_types
goodboy:asyncio_debug_mode
goodboy:pause_from_sync_w_greenback
goodboy:mv_to_new_trio_py3.11
goodboy:modden_spawn_from_client_req_XPS_BACKUP
goodboy:shielded_ctx_cancel
goodboy:ctx_cancel_semantics_and_overruns_XPS_GH_BACKUP
goodboy:msgtypes
goodboy:master
goodboy:switch_to_pdbp
goodboy:proper_breakpoint_hooking
goodboy:drop_proc_actxmngr
goodboy:ctx_result_consumption
goodboy:readme_touchups
goodboy:ipython_integration
goodboy:breceiver_internals
goodboy:ipc_failure_while_streaming
goodboy:deprecate_arbiter_addr
goodboy:prompt_on_ctrlc
goodboy:dun_unset_current_actor
goodboy:ipc_failwhilestream_backup
goodboy:macos_in_ci
goodboy:harden_cluster_tests
goodboy:eg_backup
goodboy:exceptiongroups
goodboy:egs_with_ctx_res_consumption
goodboy:debug_lock_blocking
goodboy:callable_key_maybe_open_context
goodboy:spawn_backend_table
goodboy:pin_pre_trio_0.22
goodboy:pytest_report_workaround
goodboy:lifetime_stack_tests
goodboy:we_bein_all_matchy
goodboy:debug_event_guard
goodboy:disable_win_ci
goodboy:alpha5
goodboy:signint_saviour
goodboy:sigintsaviour_citesthackin
goodboy:sigintsaviour_ci_worked
goodboy:aio_error_propagation
goodboy:drop_msgpack
goodboy:310_windows
goodboy:ci_sdist_install
goodboy:include_readme
goodboy:310_plus
goodboy:name_query
goodboy:sort_subs_results_infected_aio
goodboy:aio_explicit_task_cancels
goodboy:fence_mp
goodboy:sigint_ignore_in_pdb_repl
goodboy:sigint2
goodboy:msgpack_lists_by_default
goodboy:nspaths
goodboy:experimental_subpkg
goodboy:maybe_cancel_the_cancel_
goodboy:moar_timeoutz
goodboy:drop_old_nooz_files
goodboy:raise_runinactor_error
goodboy:win_ci_timeout
goodboy:alpha4
goodboy:infect_asyncio
goodboy:expected_ctx_cancelled
goodboy:new_mypy
goodboy:context_caching
goodboy:end_of_channel_fixes
goodboy:agpl_commit_msg_fix
goodboy:agpl
goodboy:stricter_context_starting
goodboy:acked_backup
goodboy:faster_daemon_cancels
goodboy:early_deth_fixes
goodboy:clusters_and_hot_tips
goodboy:alpha3
goodboy:pubsub_startup_response_msg
goodboy:iaio_backup
goodboy:trionics
goodboy:graceful_gather
goodboy:246_facepalm_backup
goodboy:patch-async-enter-all
goodboy:immediate_remote_cancels
goodboy:less_logging
goodboy:zombie_lord_infinite
goodboy:optional_msgspec_support
goodboy:fix_kbi_in_ctx_block
goodboy:logo_tweaks
goodboy:use_trio_on_win
goodboy:alpha2
goodboy:msgspec_infect_asyncio
goodboy:live_on_air_from_tokio
goodboy:tokio_backup
goodboy:debugger_test_tweaks
goodboy:fix_news_links
goodboy:wats_da_nooz
goodboy:ctx_debugger
goodboy:bi_streaming_no_debugger_stuff
goodboy:round_2_ci_windows
goodboy:CI_increment_for_windows_bidirstreaming
goodboy:ctx_debugger_from_hardening
goodboy:infect_asyncio_backup
goodboy:debugger_hardening
goodboy:bi_streaming
goodboy:transport_cleaning
goodboy:context_finesse
goodboy:cf_backup
goodboy:db_backup
goodboy:pre_bad_close
goodboy:stdstream_clobber_fix
goodboy:bistream_backup
goodboy:transport_hardening
goodboy:msgspec_not_fucked
goodboy:try_msgspec
goodboy:prehardkill
goodboy:windows_bi_streaming
goodboy:docs_revamp
goodboy:new_docs_polish
goodboy:wip_fix_asyncio_gen_streaming
goodboy:drop_run
goodboy:mp_teardown_hardening
goodboy:stream_contexts
goodboy:drop_sync_funcs
goodboy:pub_connect_msg
goodboy:sync_cancel
goodboy:stream_clones
goodboy:first_pypi_release
goodboy:single_func_example
goodboy:readme_pump
goodboy:kinda_drop_run
goodboy:mp_hang_search
goodboy:eg_worker_poolz
goodboy:sync_breakpoint
goodboy:actor_state_via_messages
goodboy:we_aint_got_zombie_shields
goodboy:deprecate_rpcmodpaths
goodboy:implicit_runtime
goodboy:drop_tractor_run
goodboy:py3.9
goodboy:denoise_logging
goodboy:func_refs_always
goodboy:fix_debug_tests_in_ci_again
goodboy:stream_channel_shield
goodboy:pdb_madness
goodboy:advanced_debugger_testing
goodboy:clean_log_header
goodboy:debug_refine
goodboy:debug_refinements
goodboy:drop_warn
goodboy:multiproc_debug
goodboy:debugger_on_windows
goodboy:bug_in_debug
goodboy:debug_tests
goodboy:native_debugging
goodboy:matrix
goodboy:dereg_on_channel_aclose
goodboy:ensure_deregister
goodboy:start_up_sequence_trickery
goodboy:fix_win_ci_again
goodboy:stin_char_relay
goodboy:flaky_tests
goodboy:drop_cloudpickle
goodboy:reorg_entry_points
goodboy:drop-trip-update-trio
goodboy:init_sphinx_docs
goodboy:example_tests
goodboy:implicit_rpc
goodboy:fix_examples_in_docs
goodboy:try_trip
goodboy:log_task_context
goodboy:drop_event_clear
goodboy:more_thorough_super_tests
goodboy:pip_ci_fix
goodboy:windows_support
goodboy:rename_forkserver_mod
goodboy:user_update
goodboy:win_ci
goodboy:stream_functions
goodboy:propagate_loglevel
goodboy:ipc_iternals_renaming
goodboy:close_mem_chans
goodboy:docs_example_fixes
goodboy:spawn_method_support
goodboy:trio_memchans
goodboy:contexts
goodboy:remote_module_errors
goodboy:remote_task_cancelling
goodboy:fix_46
goodboy:loglevel_to_tractor_tests
goodboy:expose_tractor_test
goodboy:improved_errors
goodboy:self_register
goodboy:multi_program_tests
goodboy:tests_reorg
goodboy:type_annotations
goodboy:py3.7_tweaks
goodboy:reliable_cancel_tests
goodboy:attrs_it_up
goodboy:wait_for_actor
goodboy:draft_readme
goodboy:init_docs
goodboy:reg_with_uid
goodboy:forkserver_singleton
goodboy:drop_main_kwarg
goodboy:asyncgen_closing_fix
No reviewers
Labels
Clear labels
No items
No Label
Milestone
Clear milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
Clear assignees
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.
No due date set.
Dependencies
No dependencies set.
Reference: goodboy/tractor#11
Reference in New Issue
There is no content yet.
Delete Branch "ctx_cancel_semantics_and_overruns"
Deleting a branch is permanent. Although the deleted branch may exist for a short time before cleaning up, in most cases it CANNOT be undone. Continue?
Namely a newly rebased with various directly related cherries from surrounding more recent dev branches over the past (wow) couple years.. 🫣
The original GH PR is here and I will be pushing to that remote likely to land it there once other dependent branches have been appropriately rebased onto this.
https://github.com/goodboy/tractor/pull/357
ToDo before this lands on GH
._context: movingPortal.open_context()there._rpc: factored out of._runtime._testingsubpkgtest_context_cancel_semantics,test_interpeer_cancellation,test_context_stream_semantics,test_child_manages_service_nursery.. etc.Landed in https://github.com/goodboy/tractor/pull/357
Definitely needs some cleaning and refinement but this gets us to stage 1 of being pretty frickin correct i'd say 💃As part of solving some final edge cases todo with inter-peer remote cancellation (particularly a remote cancel from a separate actor tree-client hanging on the request side in `modden`..) I needed less dense, more line-delimited log msg formats when understanding ipc channel and context cancels from console logging; this adds a ton of that to: - `._invoke()` which now does, - better formatting of `Context`-task info as multi-line `'<field>: <value>\n'` messages, - use of `trio.Task` (from `.lowlevel.current_task()` for full rpc-func namespace-path info, - better "msg flow annotations" with `<=` for understanding `ContextCancelled` flow. - `Actor._stream_handler()` where in we break down IPC peers reporting better as multi-line `|_<Channel>` log msgs instead of all jammed on one line.. - `._ipc.Channel.send()` use `pformat()` for repr of packet. Also tweak some optional deps imports for debug mode: - add `maybe_import_gb()` for attempting to import `greenback`. - maybe enable `stackscope` tree pprinter on `SIGUSR1` if installed. Add a further stale-debugger-lock guard before removal: - read the `._debug.Lock.global_actor_in_debug: tuple` uid and possibly `maybe_wait_for_debugger()` when the child-user is known to have a live process in our tree. - only cancel `Lock._root_local_task_cs_in_debug: CancelScope` when the disconnected channel maps to the `Lock.global_actor_in_debug`, though not sure this is correct yet? Started adding missing type annots in sections that were modified.In order to match a very significant and coming-soon patch set to the IPC `Context` and `Channel` cancellation semantics with significant but subtle changes to the primitives and runtime logic: - a new set of `Context` state pub meth APIs for checking exact inter-actor-linked-task outcomes such as `.outcome`, `.maybe_error`, and `.cancel_acked`. - trying to move away from `Context.cancelled_caught` usage since the semantics from `trio` don't really map well (in terms of cancel requests and how they result in cancel-scope graceful closure) and `.cancel_acked: bool` is a better approach for IPC req-resp msging. - change test usage to access `._scope.cancelled_caught` directly. - more pedantic ctxc-raising expects around the "type of self cancellation" and final outcome in ctxc cases: - `ContextCancelled` is raised by ctx (`Context.result()`) consumer methods when `Portal.cancel_actor()` is called (since it's an out-of-band request) despite `Channel._cancel_called` being set. - also raised by `.open_context().__aexit__()` on close. - `.outcome` is always `.maybe_error` is always one of `._local/remote_error`.Spanning from the pub API, to instance `repr()` customization (for logging/REPL content), to the impl details around the notion of a "final outcome" and surrounding IPC msg draining mechanics during teardown. A few API and field updates: - new `.cancel_acked: bool` to replace what we were mostly using `.cancelled_caught: bool` for but, for purposes of better mapping the semantics of remote cancellation of parallel executing tasks; it's set only when `.cancel_called` is set and a ctxc arrives with a `.canceller` field set to the current actor uid indicating we requested and received acknowledgement from the other side's task that is cancelled gracefully. - strongly document and delegate (and prolly eventually remove as a pub attr) the `.cancelled_caught` property entirely to the underlying `._scope: trio.CancelScope`; the `trio` semantics don't really map well to the "parallel with IPC msging" case in the sense that for us it breaks the concept of the ctx/scope closure having "caught" something instead of having "received" a msg that the other side has "acknowledged" (i.e. which for us is the completion of cancellation). - new `.__repr__()`/`.__str__()` format that tries to tersely yet comprehensively as possible display everything you need to know about the 3 main layers of an SC-linked-IPC-context: * ipc: the transport + runtime layers net-addressing and prot info. * rpc: the specific linked caller-callee task signature details including task and msg-stream instances. * state: current execution and final outcome state of the task pair. * a teensie extra `.repr_rpc` for a condensed rpc signature. - new `.dst_maddr` to get a `libp2p` style "multi-address" (though right now it's just showing the transport layers so maybe we should move to to our `Channel`?) - new public instance-var fields supporting more granular remote cancellation/result/error state: * `.maybe_error: Exception|None` for any final (remote) error/ctxc which computes logic on the values of `._remote_error`/`._local_error` to determine the "final error" (if any) on termination. * `.outcome` to the final error or result (or `None` if un-terminated) * `.repr_outcome()` for a console/logging friendly version of the final result or error as needed for the `.__str__()`. - new private interface bits to support all of ^: * a new "no result yet" sentinel value, `Unresolved`, using a module level class singleton that `._result` is set too (instead of `id(self)`) to both determine if and present when no final result from the callee has-yet-been/was delivered (ever). => really we should get rid of `.result()` and change it to `.wait_for_result()` (or something)u * `_final_result_is_set()` predicate to avoid waiting for an already delivered result. * `._maybe_raise()` proto-impl that we should use to replace all the `if re:` blocks it can XD * new `._stream: MsgStream|None` for when a stream is opened to aid with the state repr mentioned above. Tweaks to the termination drain loop `_drain_to_final_msg()`: - obviously (obvi) use all the changes above when determining whether or not a "final outcome" has arrived and thus breaking from the loop ;) * like the `.outcome` `.maybe_error` and `._final_ctx_is_set()` in the `while` pred expression. - drop the `_recv_chan.receive_nowait()` + guard logic since it seems with all the surrounding (and coming soon) changes to `Portal.open_context()` using all the new API stuff (mentioned in first bullet set above) we never hit the case of inf-block? Oh right and obviously a ton of (hopefully improved) logging msg content changes, commented code removal and detailed comment-docs strewn about!Like how we set `Context._cancel_msg` in `._deliver_msg()` (in which case normally it's an `{'error': ..}` msg), do the same when any RPC task is remotely cancelled via `Actor._cancel_task` where that task doesn't yet have a cancel msg set yet. This makes is much easier to distinguish between ctx cancellations due to some remote error vs. Explicit remote requests via any of `Actor.cancel()`, `Portal.cancel_actor()` or `Context.cancel()`.Found exactly why trying this won't work when playing around with opening workspaces in `modden` using a `Portal.open_context()` back to the 'bigd' root actor: the RPC machinery only registers one entry in `Actor._contexts` which will get overwritten by each task's side and then experience race-based IPC msging errors (eg. rxing `{'started': _}` on the callee side..). Instead make opening a ctx back to the self-actor a runtime error describing it as an invalid op. To match: - add a new test `test_ctx_with_self_actor()` to the context semantics suite. - tried out adding a new `side: str` to the `Actor.get_context()` (and callers) but ran into not being able to determine the value from in `._push_result()` where it's needed to figure out which side to push to.. So, just leaving the commented arg (passing) in the runtime core for now in case we can come back to trying to make it work, tho i'm thinking it's not the right hack anyway XDAs mentioned in description, landed in https://github.com/goodboy/tractor/pull/357 B)
Pull request closed