Package com.tnsai.cancellation
Interface CancellationToken
public interface CancellationToken
Cooperative cancellation primitive for long-running agent operations
(issue #22). Passed through to
Agent chat,
tool execution, and LLM streaming so callers can abort multi-step
work from another thread.
Semantics:
- Cooperative — observed code must check
isCancelled()at safe points or callthrowIfCancelled(). The token does not interrupt threads. - One-shot — once cancelled, stays cancelled. Subsequent
cancel(...)calls are ignored (the first reason wins). - Callbacks fire once —
onCancel(Runnable)registered before cancel runs at cancel-time; registered after cancel runs synchronously on registration so the caller never has to deal with "did I miss the event" races. - Thread-safe — every method is safe to call from any thread.
Two factories cover the common cases:
create()— fresh observable token. Caller keeps a reference to callcancel(String)when needed.none()— singleton no-op. Use as the default in method signatures so callers that don't need cancellation can pass it without allocation.
Future integration (tracked under #22 follow-ups) wires the token
into Agent.chat(message, token) overloads, AgentToolExecutor
pre-call checks, and LLM streaming chunk handlers.
- Since:
- 0.5.0 (issue #22)
-
Method Summary
Modifier and TypeMethodDescriptionvoidMark the token as cancelled and run any registered callbacks.static CancellationTokencreate()Factory for an observable cancellation token.booleanTrue after the token has been cancelled.static CancellationTokennone()Singleton no-op token that never cancels.voidRegister a callback to fire when (or if) the token is cancelled.reason()Reason supplied tocancel(String), if any.default voidThrowsCancellationExceptionif the token is cancelled.
-
Method Details
-
isCancelled
boolean isCancelled()True after the token has been cancelled. Cheap — safe to poll. -
reason
Reason supplied tocancel(String), if any. Empty for fresh or no-op tokens. -
cancel
Mark the token as cancelled and run any registered callbacks. Idempotent — only the first call has an effect; subsequent calls (with potentially different reasons) are ignored.- Parameters:
reason- short human-readable explanation; surfaces in audit logs and theCancellationExceptionmessage- Throws:
NullPointerException- ifreasonis null
-
onCancel
Register a callback to fire when (or if) the token is cancelled. Callbacks registered after cancellation already happened run immediately on the calling thread — observers never miss the event.Callbacks SHOULD be short and non-blocking. Exceptions thrown by callbacks are logged at WARN and swallowed; one bad listener cannot prevent others from running.
- Throws:
NullPointerException- ifcallbackis null
-
throwIfCancelled
default void throwIfCancelled()ThrowsCancellationExceptionif the token is cancelled. Convenience for code that wants to abort with a single line at a safe point. -
create
Factory for an observable cancellation token. -
none
Singleton no-op token that never cancels. Use as the default argument when a method accepts a token but the caller doesn't need cancellation.
-