A retry helper maps observed failures into a bounded plan.

plan A small result struct can carry related decisions back to the caller.
bounds Bounded retry plans keep a workflow predictable and easy to trace.

Retry Plan

failures
retry_plan.cpp
Replay: real traced execution (multi-file project)
#include <iostream>

struct RetryPlan {
    int attempts;
    int delay;
};

RetryPlan planRetries(int failures) {
    if (failures == 0) {
        return {1, 0};
    }
    if (failures < 3) {
        return {3, 5};
    }
    return {5, 10};
}

int main() {
    int failures = 1;

    RetryPlan plan = planRetries(failures);
    int totalDelay = plan.attempts * plan.delay;

    std::cout << "failures=" << failures << std::endl;
    std::cout << "attempts=" << plan.attempts << std::endl;
    std::cout << "totalDelay=" << totalDelay << std::endl;
    return 0;
}
#include <iostream>

struct RetryPlan {
    int attempts;
    int delay;
};

RetryPlan planRetries(int failures) {
    if (failures == 0) {
        return {1, 0};
    }
    if (failures < 3) {
        return {3, 5};
    }
    return {5, 10};
}

int main() {
    int failures = 0;

    RetryPlan plan = planRetries(failures);
    int totalDelay = plan.attempts * plan.delay;

    std::cout << "failures=" << failures << std::endl;
    std::cout << "attempts=" << plan.attempts << std::endl;
    std::cout << "totalDelay=" << totalDelay << std::endl;
    return 0;
}
#include <iostream>

struct RetryPlan {
    int attempts;
    int delay;
};

RetryPlan planRetries(int failures) {
    if (failures == 0) {
        return {1, 0};
    }
    if (failures < 3) {
        return {3, 5};
    }
    return {5, 10};
}

int main() {
    int failures = 4;

    RetryPlan plan = planRetries(failures);
    int totalDelay = plan.attempts * plan.delay;

    std::cout << "failures=" << failures << std::endl;
    std::cout << "attempts=" << plan.attempts << std::endl;
    std::cout << "totalDelay=" << totalDelay << std::endl;
    return 0;
}
  1. failures ← 1

    18int main() {19    int failures→ 1 = 1; //@failures=0, 42021    RetryPlan plan = planRetries(failures1);22    int totalDelay = plan.attempts * plan.delay;
  2. RetryPlan planRetries(int failures)

    8RetryPlan planRetries(int failures1) {9    if (failures == 0) {
  3. if (failures < 3)

    11}12if (failures1 < 3) {13    return {3, 5};14}
  4. plan ← (empty), totalDelay ← 15

    21    RetryPlan plan→ (empty) = planRetries(failures1);22    int totalDelay→ 15 = plan.attempts3 * plan.delay5;2324    std::cout << "failures=" << failures1 << std::endl;25    std::cout << "attempts=" << plan(empty).attempts << std::endl;26    std::cout << "totalDelay=" << totalDelay15 << std::endl;27    return 0;28}
    outputfailures=1
    attempts=3
    totalDelay=15
  1. failures ← 0

    18int main() {19    int failures→ 0 = 0;2021    RetryPlan plan = planRetries(failures0);22    int totalDelay = plan.attempts * plan.delay;
  2. RetryPlan planRetries(int failures)

    8RetryPlan planRetries(int failures0) {9    if (failures == 0) {
  3. if (failures == 0)

    8RetryPlan planRetries(int failures) {9    if (failures0 == 0) {10        return {1, 0};11    }
  4. plan ← (empty), totalDelay ← 0

    21    RetryPlan plan→ (empty) = planRetries(failures0);22    int totalDelay→ 0 = plan.attempts1 * plan.delay0;2324    std::cout << "failures=" << failures0 << std::endl;25    std::cout << "attempts=" << plan(empty).attempts << std::endl;26    std::cout << "totalDelay=" << totalDelay0 << std::endl;27    return 0;28}
    outputfailures=0
    attempts=1
    totalDelay=0
  1. failures ← 4

    18int main() {19    int failures→ 4 = 4;2021    RetryPlan plan = planRetries(failures4);22    int totalDelay = plan.attempts * plan.delay;
  2. RetryPlan planRetries(int failures)

    8RetryPlan planRetries(int failures4) {9    if (failures == 0) {10        return {1, 0};11    }12    if (failures < 3) {13        return {3, 5};14    }15    return {5, 10};16}
  3. plan ← (empty), totalDelay ← 50

    21    RetryPlan plan→ (empty) = planRetries(failures4);22    int totalDelay→ 50 = plan.attempts5 * plan.delay10;2324    std::cout << "failures=" << failures4 << std::endl;25    std::cout << "attempts=" << plan(empty).attempts << std::endl;26    std::cout << "totalDelay=" << totalDelay50 << std::endl;27    return 0;28}
    outputfailures=4
    attempts=5
    totalDelay=50