interrupt

suspend fun <State> interrupt(state: State): Nothing

Pauses the run from inside a node and saves state. Use it when a node finds out in the middle of its work that it needs a person, for example to ask a question it only knows at run time.

The call never returns. The run ends with GraphResult.Interrupted, which holds state, and CompiledGraph.resume runs the node again. Put the question into state and let resume write the answer into the state, so that the node can tell the two runs apart:

val refund = node("refund") { order ->
val amount = refundFor(order)
// Nobody has decided yet: save the question and stop here.
if (order.approved == null) interrupt(order.copy(question = "Refund $amount?"))
if (order.approved) pay(order, amount)
order.copy(question = null)
}

val paused = graph.invoke(order, config) // Interrupted, with the question in its state
graph.resume(config) { it.copy(approved = true) } // runs "refund" again, now with the answer

What to know:

  • The node starts again from its first line. What it did before the call happens a second time, so call interrupt before a side effect, or make the side effect safe to repeat.

  • The step is not saved. When other nodes run in the same step, they are cancelled, and resume runs all of them again with state as their input. If two nodes of a step call interrupt, the first one pauses the run and the other one asks after the next resume.

  • It needs a checkpointer. Without one the run fails with a GraphValidationException.

  • A run that paused here does not pause again before the same nodes because of GraphConfig.interruptBefore.

Call it from the action of a node, or from the work of a node with a work and an update, with a state of the graph's type. A try around the call must not catch Throwable, and runCatching does: the node would then go on instead of pausing.

Throws

when it is not called from a node of a running graph.