-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make async mqtt client implement Send #461
Conversation
There were already some Send implementations. However, they weren't completely correct, which made it impossible to use the async mqtt client in e.g. a tokio worker thread. Note that it could be used in the async main task, because that never sends off any work to other worker threads, and thus Send is not required. The errors would surface when trying to use tokio::spawn with an async mqtt client.
@@ -182,8 +182,8 @@ where | |||
} | |||
} | |||
|
|||
unsafe impl<T> Send for Channel<T> where T: Send + 'static {} | |||
unsafe impl<T> Sync for Channel<T> where T: Send + 'static {} | |||
unsafe impl<'a, T> Send for Channel<T> where T: Send + 'a {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
To use Most of the futures in With that said, I agree that if it is relatively easy to make the futures of some driver/service Ah! I take my words back for the
Yes! This is spot-on. Would you enhance the PR with this fix? Basically |
Yes, I believe this is a limitation in the current rust compiler. Essentially, rust does not understand that the original bound is enough. The new bound unsafe impl<'a, T> Send for Receiver<T> where T: Send + 'a {} essentially says, for all lifetimes |
Oof. That sounds horrible. 😭 |
Since the Need to review if we need the same unsafe pattern elsewhere. We might be... |
Thanks! |
Didn't you see what I mean... if you would like to contribute a truly-async client to |
Hmm. Everything I've seen seems to indicate it uses a separate thread that waits using conditional variables and that kind of stuff. But I haven't seen anything that spins (i.e. looping using a short delay, which is how I interpret "spin"). |
My English. :) I didn't mean to say that we busyloop by polling stuff with short sleeps in-between. That would truly be indeed very horrible. By "spinning" I meant simply that the blocking MQTT ESP IDF client is turned into an async one by working it in a separate thread and then delegating to that separate thread the execution. And using condvars to sync indeed. Still pretty gross, as that's not a "native" async. A bit like the hack how |
Ah. I see! |
There were already some Send implementations.
However, they weren't completely correct, which made it impossible to use the async mqtt client in e.g. a tokio worker thread.
Note that it could be used in the async main task, because that never sends off any work to other worker threads, and thus Send is not required. The errors would surface when trying to use tokio::spawn with an async mqtt client.
See also https://users.rust-lang.org/t/implementation-of-send-is-not-general-enough-but-cannot-make-it-more-general/115087
Also. I note that the Unblocker deletes the FreeRTOS task when it is dropped. This seems sketchy. Deleting the task will, if I understand correctly, cause it to stop running immediately, without running any associated
Drop
implementations. Couldn't this cause memory leaks? Wouldn't it be better to just let it close the channel and let the worker thread clean itself up?