PIXELBANKv9.1.0
Menu

Fallback Chain under a Deadline and Step Budget

Problem Statement

A production agent never has one way to answer a question - it has a chain: the fast cheap model, then the strong expensive one, then the cached stale answer, then a canned apology. What makes the chain safe is that it runs under two hard limits at once: a wall-clock deadline and a step budget. Without them, a chain of three flaky providers is just three ways to blow your latency SLO.

Background

The chain is tried in order. Before each attempt, both guards are checked:

  1. Step budget. If the number of attempts already made equals max_steps, stop with status step_budget_exhausted.
  2. Deadline. If elapsed + latency_ms for the next provider would exceed deadline_ms, do not attempt it - stop with status deadline_exceeded. The guard is predictive: you never start a call you already know cannot finish in time.

If both guards pass, the provider is attempted: it costs its full latency_ms and one step whether it succeeds or fails. A success ends the run with status ok. A failure moves to the next provider. Running off the end of the chain is status exhausted.

Your Task

Implement:

def execute_with_fallback(chain, outcomes, deadline_ms, max_steps):
  • chain: ordered list of {"name": str, "latency_ms": int}.
  • outcomes: dict of provider name -> "ok" or "error". A name missing from the dict counts as "error".

Return a dict with:

  • status: "ok", "deadline_exceeded", "step_budget_exhausted" or "exhausted"
  • provider: the winning provider's name, or "" when there is none
  • elapsed_ms: total milliseconds consumed by attempts actually made
  • steps: number of attempts actually made
  • attempted: the provider names attempted, in order

Input/Output Format

Returns the five-key dict above. All the numbers are ints - nothing here is floating point.

Sample

chain = [{"name": "fast", "latency_ms": 100}, {"name": "strong", "latency_ms": 400}]
print(execute_with_fallback(chain, {"strong": "ok"}, 1000, 5)["provider"])   # strong
print(execute_with_fallback(chain, {"strong": "ok"}, 400, 5)["status"])      # deadline_exceeded

In the second call fast fails after 100ms, and 100 + 400 > 400, so strong is never started.

Example:

Input:
chain = [{'name':'fast','latency_ms':100},{'name':'strong','latency_ms':400}]
print(execute_with_fallback(chain, {'strong':'ok'}, 1000, 5)['provider'])
print(execute_with_fallback(chain, {'strong':'ok'}, 400, 5)['status'])
Output:
strong
deadline_exceeded
Reasoning:

With a 1000ms deadline, fast is attempted (100ms, fails since it is absent from outcomes), then strong is attempted and succeeds at 500ms total. With a 400ms deadline, fast still costs 100ms, but 100 + 400 = 500 > 400, so the predictive guard blocks strong before it starts.

Constraints:

  • 0 <= len(chain) <= 50; latency_ms >= 0; deadline_ms >= 0; max_steps >= 0
  • Both guards are checked before each attempt, step budget first
  • The deadline guard is predictive: elapsed + latency_ms > deadline_ms blocks the attempt
  • A failed attempt still costs its full latency and one step
  • A provider missing from outcomes is treated as "error"
  • provider is "" for every non-ok status
🔒

Editor locked

The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.

solution.py

Test Results

0/0
Run code to see test results.
Fallback Chain under a Deadline and Step Budget - Medium | PixelBank