|
NeoGraph 0.10.0
A C++17 Graph Agent Engine Library — LangGraph for C++
|
Cooperative cancel primitive shared between caller and engine. More...
#include <cancel.h>
Public Member Functions | |
| void | bind_executor (asio::any_io_executor ex) |
Bind the executor that will handle cancellation_signal emits. | |
| void | cancel () noexcept |
| Request cancellation. | |
| std::shared_ptr< CancelToken > | fork () |
| Create a child token that cascades from this one. | |
| bool | is_cancelled () const noexcept |
| Polling read of the cancel flag. Cheap, lock-free. | |
| asio::cancellation_slot | slot () noexcept |
Cancellation slot for binding to a coroutine via asio::bind_cancellation_slot at co_spawn. | |
| void | throw_if_cancelled (const std::string &detail={}) const |
Throws CancelledException if cancelled. | |
Cooperative cancel primitive shared between caller and engine.
Construction is cheap (one atomic + one asio::cancellation_signal). Pass via RunConfig::cancel_token (shared_ptr) to opt in. Re-entrant: cancel() is idempotent; callers may share the token across concurrent runs to fan out a single abort.
|
inline |
Bind the executor that will handle cancellation_signal emits.
Called once by the engine's run-spawn lambda.
If cancel() has already been requested (caller cancelled before the run started) the bind also schedules an immediate emit so the just-spawned coroutine unwinds at its first co_await checkpoint.
|
inlinenoexcept |
Request cancellation.
Thread-safe, idempotent.
Sets the polling flag immediately so subsequent is_cancelled() checks return true. Posts the asio signal emit onto the bound executor so any in-flight co_await — including the LLM HTTP socket operation — receives an operation_aborted error and unwinds cleanly.
Safe to call before bind_executor(): in that case only the polling flag is set; whoever later binds the executor will notice via is_cancelled() before any HTTP work has begun.
|
inline |
Create a child token that cascades from this one.
Each child has its own cancellation_signal, so concurrent consumers (multi-Send fan-out workers each calling Provider::complete → run_sync with its own io_context) never overwrite each other's cancellation slot. Calling cancel() on the parent walks the live children list and cascades — every child's signal fires on its own bound executor.
Lifetime / ownership: returns a shared_ptr<CancelToken>; the parent stores a weak_ptr so a forked child that goes out of scope is automatically pruned from the cascade list on the next cancel() / fork(). The parent itself can outlive its children freely.
Eager-cancel safety: if the parent is already cancelled at the time of fork(), the new child is constructed with its polling flag pre-set (is_cancelled() == true). When the caller subsequently bind_executor s the child, the eager- emit branch in bind_executor fires the child's signal on its first co_await checkpoint. This closes the v0.3.2 "emit-vs-bind race" without an explicit short-circuit at every consumer site.
Pass-by-value into a coroutine frame is fine — shared_ptr copy is cheap and the parent reference inside the child stays valid via shared ownership of the parent. (PR 2 trap shape does NOT apply.)
|
inlinenoexcept |
Cancellation slot for binding to a coroutine via asio::bind_cancellation_slot at co_spawn.
asio propagates the cancel through nested co_awaits down to socket operations.
Slots are not thread-safe; this is consumed once by the spawn site, then never read again by user code.
|
inline |
Throws CancelledException if cancelled.
Convenience wrapper used at engine super-step boundaries.