Task dependencies of futures. How to design a common API?

⚓ Rust    📅 2026-07-13    👤 surdeus    👁️ 4      

surdeus

I have an implementation of a Zigbee driver and want to now abstract away its builder via trait in the used Zigbee library (apis-saltans).

This is the current method in question:

I now face the issue that I have a goal that make this quite challenging, namely I want the API to be async runtime-agnostic.

As you can see from the linked code, the function currently internally spawns new tasks, on which the following operations depend. I.e. those futures must be awaited in order for some following code to be able to proceed. This is currently hard-coded via tokio::spawn. However, I want the user to be able to use a runtime of their choosing.
So how can I create arbitrary futures inside an async function, i.e. a function that returns a future itself and hand those dependecy-futures back to the caller while conveying, ideally by means of the type system, that those shall be spawned before awaiting the main future?

One possible solution that came to my mind, was to pass in an MPSC sender to the function as well, which receives those internally created futures of the task dependencies, then return some wrapper object, that, when awaited, first spawns the dependencies, before resolving to the actual return type of the built NCP / Event receiver tuple.

This, however also has the issue, that I just moved the problem. In order to spawn the tasks internally in such a return type wrapper, I must let the user pass in an appropriate spawn function of their chosen runtime. But there is currently no such thing as a common API for that. I.e. e.g. async_std::task::spawn and tokio::spawn don't implement a common stable API.

Furthermore, such a return type and the necessity to pass in such a sender makes the whole kerfuffle even more complicated than it already is.

So my question is, whether there are established patterns and / or crates to handle a situation in which I have a common API with a future that resolves to a type, which may internally spawn task-dependencies in an async runtime-agnostic manner.

1 post - 1 participant

Read full topic

🏷️ Rust_feed