A retry state machine can alternate between ready and waiting, then stop after too many failures.

guard A guard condition can stop the machine before normal alternation continues.
retry The state tells the caller whether to try now, wait, or stop.

Retry State

failures
retry_state.c
Replay: real traced execution (multi-file project)
#include <stdio.h>

enum RetryState {
    RETRY_READY,
    RETRY_WAITING,
    RETRY_STOPPED
};

enum RetryState nextRetry(enum RetryState state, int failures) {
    if (failures >= 3) {
        return RETRY_STOPPED;
    }
    if (state == RETRY_READY) {
        return RETRY_WAITING;
    }
    return RETRY_READY;
}

int main(void) {
    int failures = 1;
    enum RetryState state = RETRY_READY;

    state = nextRetry(state, failures);
    state = nextRetry(state, failures + 1);

    printf("failures=%d state=%d\n", failures, state);
    return 0;
}
#include <stdio.h>

enum RetryState {
    RETRY_READY,
    RETRY_WAITING,
    RETRY_STOPPED
};

enum RetryState nextRetry(enum RetryState state, int failures) {
    if (failures >= 3) {
        return RETRY_STOPPED;
    }
    if (state == RETRY_READY) {
        return RETRY_WAITING;
    }
    return RETRY_READY;
}

int main(void) {
    int failures = 0;
    enum RetryState state = RETRY_READY;

    state = nextRetry(state, failures);
    state = nextRetry(state, failures + 1);

    printf("failures=%d state=%d\n", failures, state);
    return 0;
}
#include <stdio.h>

enum RetryState {
    RETRY_READY,
    RETRY_WAITING,
    RETRY_STOPPED
};

enum RetryState nextRetry(enum RetryState state, int failures) {
    if (failures >= 3) {
        return RETRY_STOPPED;
    }
    if (state == RETRY_READY) {
        return RETRY_WAITING;
    }
    return RETRY_READY;
}

int main(void) {
    int failures = 3;
    enum RetryState state = RETRY_READY;

    state = nextRetry(state, failures);
    state = nextRetry(state, failures + 1);

    printf("failures=%d state=%d\n", failures, state);
    return 0;
}
  1. failures ← 1

    19int main(void) {20    int failures→ 1 = 1; //@failures=0, 321    enum RetryState state = RETRY_READY;2223    state0 = nextRetry(state, failures1);24    state = nextRetry(state, failures + 1);
  2. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 1 of 2
    9enum RetryState nextRetry(enum RetryState state0, int failures1) {10    if (failures >= 3) {
  3. if (state == RETRY_READY)

    12}13if (state0 == RETRY_READY0) {14    return RETRY_WAITING1;15}
  4. state ← 1

    23state→ 1 = nextRetry(state, failures1);24state1 = nextRetry(state, failures1 + 1);
  5. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 2 of 2
    9enum RetryState nextRetry(enum RetryState state1, int failures2) {10    if (failures >= 3) {11        return RETRY_STOPPED;12    }13    if (state == RETRY_READY) {14        return RETRY_WAITING;15    }16    return RETRY_READY0;17}
  6. state ← 0

    23    state = nextRetry(state, failures);24    state→ 0 = nextRetry(state, failures1 + 1);2526    printf("failures=%d state=%d\n", failures1, state0);27    return 0;28}
    outputfailures=1 state=0
  1. failures ← 0

    19int main(void) {20    int failures→ 0 = 0;21    enum RetryState state = RETRY_READY;2223    state0 = nextRetry(state, failures0);24    state = nextRetry(state, failures + 1);
  2. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 1 of 2
    9enum RetryState nextRetry(enum RetryState state0, int failures0) {10    if (failures >= 3) {
  3. if (state == RETRY_READY)

    12}13if (state0 == RETRY_READY0) {14    return RETRY_WAITING1;15}
  4. state ← 1

    23state→ 1 = nextRetry(state, failures0);24state1 = nextRetry(state, failures0 + 1);
  5. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 2 of 2
    9enum RetryState nextRetry(enum RetryState state1, int failures1) {10    if (failures >= 3) {11        return RETRY_STOPPED;12    }13    if (state == RETRY_READY) {14        return RETRY_WAITING;15    }16    return RETRY_READY0;17}
  6. state ← 0

    23    state = nextRetry(state, failures);24    state→ 0 = nextRetry(state, failures0 + 1);2526    printf("failures=%d state=%d\n", failures0, state0);27    return 0;28}
    outputfailures=0 state=0
  1. failures ← 3

    19int main(void) {20    int failures→ 3 = 3;21    enum RetryState state = RETRY_READY;2223    state0 = nextRetry(state, failures3);24    state = nextRetry(state, failures + 1);
  2. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 1 of 2
    9enum RetryState nextRetry(enum RetryState state0, int failures3) {10    if (failures >= 3) {
  3. if (failures >= 3)

    pass 1 of 2
    9enum RetryState nextRetry(enum RetryState state, int failures) {10    if (failures3 >= 3) {11        return RETRY_STOPPED2;12    }
  4. state ← 2

    23state→ 2 = nextRetry(state, failures3);24state2 = nextRetry(state, failures3 + 1);
  5. enum RetryState nextRetry(enum RetryState state, int failures)

    pass 2 of 2
    9enum RetryState nextRetry(enum RetryState state2, int failures4) {10    if (failures >= 3) {
  6. if (failures >= 3)

    pass 2 of 2
    9enum RetryState nextRetry(enum RetryState state, int failures) {10    if (failures4 >= 3) {11        return RETRY_STOPPED2;12    }
  7. state = nextRetry(state, failures + 1);

    23    state = nextRetry(state, failures);24    state2 = nextRetry(state, failures3 + 1);2526    printf("failures=%d state=%d\n", failures3, state2);27    return 0;28}
    outputfailures=3 state=2