Call a Function
View MarkdownA Function has three ways to start a call. Each call is a FunctionCall object, so you can look it up later, wait
for it from another process or cancel it.
| Call | What it does |
|---|---|
f.remote(x) |
Runs one call and blocks until it returns its result. |
f.spawn(x) |
Starts one call and returns a handle: handle.get(timeout=...) waits, handle.cancel() stops it. |
f.map(xs) |
Starts one call per input and yields the results in input order. |
with app.run(): print(square.remote(7)) # 49 handle = square.spawn(8) print(handle.get(timeout=600)) # 64 print(list(square.map(range(1000)))) # 1,000 results, in orderMap over many inputs
Section titled “Map over many inputs”.map() creates its calls in batches of up to 1,000 per request, and a batch is all or nothing: a request that fails
leaves no calls behind, and sending it again does not create them twice. Results come back in input order whichever
worker finishes first. order_outputs=False yields them as they finish, and return_exceptions=True yields a failed
input’s exception instead of stopping the loop.
results = list(process.map(files, order_outputs=False, return_exceptions=True))Several callers can map into one Function at the same time. Workers take calls from each caller in turn, so a caller that submits 10 inputs is not stuck behind another caller’s 10,000.
Arguments and results
Section titled “Arguments and results”Arguments and results are serialized with cloudpickle. Values up to 64 KiB travel inside the call. Larger ones are uploaded once, by content hash, and the call carries a reference, so a large argument costs nothing extra to send again. The caller and the worker image must run the same Python minor version, 3.10 to 3.13.
Errors, retries and timeouts
Section titled “Errors, retries and timeouts”An exception raised inside the Function is raised again in your process as its own type when that type can be
imported there. Otherwise you get nodus.errors.RemoteError. Either way the remote traceback is attached.
try: divide.remote(1, 0)except ZeroDivisionError: ...Two things can send a call back to the queue, and they are counted separately:
- The function raised. With
retries=nodus.Retries(max_retries=3)the call is retried with exponential backoff, up to ten times. Without retries the exception ends the call. - The worker was lost. A worker that disappears or is replaced does not count as a retry. Its calls go back to the
queue and run on another worker, up to
recovery.maxAttemptstimes (eight by default), then end asFailedwith the reasonRecoveryLimitExceeded.
A call can finish only once. A result that arrives from a worker that no longer holds the call is refused, so a call that was re-dispatched never ends with two results.
Look a call up later
Section titled “Look a call up later”call = nodus.FunctionCall.from_name("fn-warm-ping-bcdfghjklm")print(call.get(timeout=60))$ nodus get functioncalls -l nodus.dev/map=<map id>$ nodus get functioncall <name> -o yaml # phase, result reference, retries, recoveries, costUSDA call keeps its result for seven days after it ends. Each call reports status.costUSD, the worker time attributed
to it; the billing page explains how it relates to what you pay.