Skip to main content
An async Tensorlake function behaves like a regular Python async function. Calling it returns a coroutine that doesn’t run until it’s awaited or started with asyncio.create_task() or other asyncio module functions.
coroutines returned by async Tensorlake functions behave almost the same way as Futures used with sync Tensorlake functions.

asyncio.create_task

Use asyncio.create_task() to run a coroutine in the background without blocking on it. This returns an asyncio.Task that can be awaited later to get the result.

Running coroutines in parallel with asyncio.gather

Use asyncio.gather() to run multiple coroutines in parallel and collect their results. This is the standard Python way to run async functions concurrently.

Non-blocking map and reduce operations

Calling function.map(...) or function.reduce(...) on an async function returns a coroutine.
The coroutines returned by function.map() or function.reduce() behave exactly the same as coroutines returned by async function(...) calls.

Passing coroutines and asyncio.Tasks as inputs

Coroutines returned from async Tensorlake functions and asyncio.Task objects created with asyncio.create_task() from such coroutines can be passed as arguments to other function calls. Tensorlake automatically runs the coroutines or asyncio.Task objects, waits for them to complete, and uses their results as the argument values. This works exactly like passing Futures as inputs.
All input coroutines that don’t depend on each other run in parallel, allowing Tensorlake to optimize resource usage and reduce overall application latency. A function call or a map-reduce operation are only blocked while their input coroutines are running. Once all input coroutines complete, Tensorlake automatically runs the function call or the map-reduce operation.

Wrapping coroutines and asyncio.Tasks into Python objects is not allowed

When passing Tensorlake coroutines or asyncio.Task objects create from them as arguments to function calls, or returning them as tail calls, they cannot be wrapped into other Python objects. For example, returning a list with a coroutine inside is not allowed. Tensorlake will not recognize the coroutine wrapped into the list. This is the same restriction as with Futures.
Map and reduce operations accept a Future/coroutine/asyncio.Task or a list as input items. If a list is passed then the Futures/coroutines/asyncio tasks in the list are recognized by Tensorlake and run automatically.

Tail calls

Returning a Tensorlake function coroutine or its asyncio.Task makes a tail call. The returning function completes immediately and its function container is freed to process the next request. Tensorlake runs the returned coroutine or task and uses its result as the function’s return value. This works exactly like returning a Future as a tail call.
Futures can also be returned as tail calls from async functions.

Calling sync functions from async functions

Sync Tensorlake functions can be called directly from async functions. The call blocks the asyncio event loop until the sync function completes. No other asyncio tasks can run while the asyncio event loop is blocked. Because of this, calling sync Tensorlake functions directly is an anti-pattern and should be avoided. Use function.future() to call sync functions without blocking the event loop. Call future.run() to start the Future in the background. Use await future to wait for the Future to complete and get its result. If this doesn’t fit the use case, use future.coroutine() to convert the Future into a coroutine that can be used the same way as any coroutine returned by an async Tensorlake function.

Calling async functions from sync functions

Sync functions cannot await coroutines. To call an async Tensorlake function from a sync function, use function.future() to create a Future and call .result() to block until it completes.

See Also

Futures

Use Futures for parallel execution and tail calls.

Map-Reduce

Parallel processing over lists of data.