Skip to content

Watch a job's state changes

ctx, stop := context.WithCancel(ctx)
defer stop()

for e := range dispatch.Watch(ctx, cluster.Observer(), job, 10*time.Second) {
    fmt.Printf("%s -> %s, cause %s, submission %d\n", e.From, e.To, e.Cause.Kind, e.Submission)

    if e.To.Terminal() {
        stop()
    }
}

dispatch.Watch polls the Observer every interval and sends each state transition on the channel it returns. It closes the channel once the context ends, and not before: it never stops on its own, so cancel the context when you have what you need, as the loop above does on a terminal state.

This is what a host uses instead of polling Get itself, as the tutorial's waitFor helper does.

What it reports

With a record store, each Event is a transition committed to the job's record, the same ones as Status.History, in order:

  • into held, when a person holds the job or a hold rule places a recovery hold;
  • into recovering, when a later submission is authorized;
  • into the terminal state, succeeded, failed or cancelled, once its outcome is committed.

The first poll sends every transition the record already holds, so a watcher started late still sees the whole history. Whether the job is running comes from what the scheduler shows when you ask, not from the record, so running is never an event. Call Get for that.

Without a store, a status can describe the job's objects only (Level is object-only). Watch then reports a change between pending and running, timed when the poll saw it, and never reports a terminal state, because an object ending is not the job ending.

Choose the interval

Every poll is one Get: a Find on the scheduler and, with a store, a read of the record. Pick an interval the scheduler can bear for every job you watch at once. A transition is reported on the first poll after it is committed, so the interval is also how late you may hear of one.

A poll that fails is skipped, and the next poll tries again. Watch doesn't report the error, so if you need to know the scheduler or the store is unreachable, call Get yourself.