A function can retry a failed call automatically. Set retries on the decorator to the number of retries after the first attempt:

import urllib.request

import chalkcompute

@chalkcompute.function(retries=3)
def fetch_status(url: str) -> int:
    with urllib.request.urlopen(url, timeout=10) as response:
        return response.status

if __name__ == "__main__":
    fetch_status.wait_ready()
    handle = fetch_status.defer("https://example.com")
    print(handle.get())  # 200

​
Which calls are retried

Retries apply to calls that go through the function queue:

  • .defer(...) calls, collected with .get() or chalkcompute.gather(...).
  • .remote(...) calls to a generator function, which Chalk sends through the queue.

A .remote(...) call to any other function does not go through the queue and is not retried. The first failure reaches the caller.


​
What triggers a retry

Any exception the function raises triggers a retry, until the function has used its retry count. Each retry starts after a fixed delay set by the function queue. When the last attempt fails, the caller receives its error as a chalkcompute.RemoteExecutionError; see Error handling.

When a generator function has retries set, Chalk holds each attempt’s output until that attempt succeeds or is the last one. The caller does not receive values from an attempt that is then retried, so a retry does not repeat values the caller already has.


​
RetryPolicy

retries also accepts a chalkcompute.RetryPolicy, built with RetryPolicy.exponential(...) or RetryPolicy.linear(...). An integer is the same as RetryPolicy.exponential(attempts=<integer>).

The function queue applies only the policy’s attempts value. The other arguments (initial, multiplier, max_wait, delay, jitter, and retry_on) have no effect on function calls: the delay between retries stays fixed, and every exception is retried whatever retry_on lists.