reconcile hook is a function that takes an effect key, asks the remote what happened, and
answers "committed", "not_executed" or "unknown". It is the only thing besides a human
permitted to move a record out of AMBIGUOUS, and it moves the record only in the direction its
answer points: "unknown" leaves it where it was.
Prerequisites: pip install ctrlrun, an empty directory. The remote is a stand-in with a
lookup the hook can call.
1
Write the hook beside the executor
The hook receives the effect key and nothing else. Parse what you need out of it; the key
was built from the arguments, so it carries the identifiers the remote indexes by.
runnable
runnable
2
Choose when it runs
With
reconcile_eagerly=True the hook runs as soon as the call produces an AMBIGUOUS
outcome. Without it, the hook runs when a later attempt is blocked by the ambiguous record,
which is the cheaper default when reconciliation costs a network call and most ambiguous
effects are never retried.3
Read the evidence
runnable
RECONCILIATION_STARTED and RECONCILIATION_RESOLVED,
with the hook’s answer. A hook that raises is recorded and the record stays AMBIGUOUS; it
is never read as an answer.The three answers
Answer
"not_executed" only when the remote told you it has no record of the effect, and the
remote is authoritative for that. A hook that answers it from a cache, or from a lookup that
can lag, has the same failure as an executor raising NotExecuted too early: it licenses a
second execution.
If it didn’t work
- The record stayed
AMBIGUOUSafter an eager reconcile: the hook returned"unknown"or raised. Both are recorded in the events. InvalidArgument: reconcile must be callable:reconcile=was given something other than a function of one argument.
Next
- Resolve an AMBIGUOUS effect: the human path.
- Outcomes and AMBIGUOUS.
- Get started · Why.