I need a second opinion on the design of async discovery of Zigbee devices.
I have a discovery::Actor, which implements the actor model and receives messages, amongst others, those of Events.
If such an event is Event::DeviceJoined(address) the actor shall start the discovery of that device.
This involves several steps:
Discovery of endpoints on the node.
Discovery of descriptors for each of the endpoints.
Discovery of a pre-dermined set of attributes for each endpoint.
Now, due to Zigbee being a fallible radio mesh networking protocol, each of these steps can fail.
So I want to have an option to retry each of the steps above until all properties are discovered.
I am facing several challenges while implementing this:
The discovery of each device shall be non-blocking in the discovery::Actor's main loop.
Steps 2 and 3 depend on step 1 having completed successfully.
Steps 2 and 3 are independent and may be parallellized.
Once any device discovery is completed, it shall forward the completely discovered device data to another actor.
Here's my current (WIP) approach:
Do you have some established patterns or tips on how I can achieve my set goals?
The pattern that immediately comes to mind would be using custompoll_foo() functions for at least steps 2 & 3 where a certain set of errors is reset to Poll::Pending.
Something along the lines of how Sockets reset blocking IO errors to Poll::Pending on poll_read_ready()etc. (A bit of an idea for that is here in futures-udp clear_ready() & poll_ready())
I'm interested to see how you get on with this lib - zigbee is about 1/3 of the way down my current todo list, so maybe I can just use yours when I get that far.
One request though: if you're creating a lib and there is any way to use futures-rs rather than tokio for the underlying foundations that guarantees to leave the choice of runtime to the app. (tokio sometimes embeds runtime-dependencies in fundamental types which means apps then have to struggle to use a different runtime of they want to for whatever reasons)