In my main thread, I create a
Manager, which itself spins up another process and abstracts the interaction with it. While most of the time commands are being performed on the Manager, I need to also get data out of it. For example,
manager.take() will perform a camera “take” on the main bus, while
manager.get_bus_status() will return a struct describing the current state of the bus. A stripped down example is here.
To send commands from the Rocket route to the main thread, I passed Rocket a
SyncChannel to manage. Then, the route can send messages which are processed in the main thread. This works really well and also allows me to provide rudimentary console input in yet another thread.
However, I also need to be able to receive data in the route. I initially thought I could create another
(sender, receiver) pair, this time specifically for the main thread to send responses to the Rocket route thread, but a Receiver does not implement Sync, which the Rocket
.manage(...) call requires.
An option posted by “athrowaway3z” was to pass a sender back through the channel itself. I can’t figure out if that’s elegant or a little crazy, but it seems to work. I modified my code to be something like this, and I’m able to pass messages back. I don’t need to use SyncChannel again in the route, so at least there’s a bit less overhead in the creation of the next channel.
In some ways, this feels really nice because it means there’s no potential for any kind of data mix-up to multiple clients since the channel is created specifically for a single HTTP request. If it’s not fulfilled that request hangs, but everything else can continue working.
Lines 24-26 seem like a lot of boilerplate that will get repeated over and over, but I may be able to wrap those in a single call. I also feel like it might not be the most performant, though that probably won’t be an issue in my application.
Is there a language feature I’m missing to streamline this scenario?