stakwork/sphinx-key

MQTT Event Bus

Closed this issue · 2 comments

From the ESP32 demo:

    // Need to immediately start pumping the connection for messages, or else subscribe() and publish() below will not work
    // Note that when using the alternative constructor - `EspMqttClient::new` - you don't need to
    // spawn a new thread, as the messages will be pumped with a backpressure into the callback you provide.
    // Yet, you still need to efficiently process each message in the callback without blocking for too long.

We cannot simply grab messages from MQTT listener and start signing and returning them. We need to efficiently process (just add to a queue?), and then process them one at a time. The proper API for this on the ESP32 is the EventBus / EspBackgroundEventLoop / EspBackgroundSubscription things.

Lets learn about how this works, and build a demo script that floods the ESP32 with MQTT messages, that can be efficiently handled

Problem with trying to publish back to MQTT from within the EventBus background callback:

   |
28 |         callback: impl for<'a> FnMut(&'a P) + Send + 'static,
   |                                               ^^^^ required by this bound in `embedded_svc::event_bus::EventBus::subscribe`

error[E0277]: `(dyn FnMut(*mut esp_mqtt_event_t) + 'static)` cannot be shared between threads safely
  --> src/core/events.rs:54:34
   |
54 |     let subscription = eventloop.subscribe(|message: &Message| {
   |                                  ^^^^^^^^^ `(dyn FnMut(*mut esp_mqtt_event_t) + 'static)` cannot be shared between threads safely
   |
   = help: the trait `Sync` is not implemented for `(dyn FnMut(*mut esp_mqtt_event_t) + 'static)`
   = note: required because of the requirements on the impl of `Sync` for `Unique<(dyn FnMut(*mut esp_mqtt_event_t) + 'static)>`
   = note: required because it appears within the type `Box<(dyn FnMut(*mut esp_mqtt_event_t) + 'static)>`
   = note: required because it appears within the type `esp_idf_svc::mqtt::client::EspMqttClient<ConnState<MessageImpl, EspError>>`
   = note: required because of the requirements on the impl of `Send` for `&esp_idf_svc::mqtt::client::EspMqttClient<ConnState<MessageImpl, EspError>>`