I am writing an axum project and want to communicate if a resource is busy. (Later this will be something like a camera that takes a few seconds to take a picture). Once one client presses a button on a website any other client shall receive a signal “resource_busy_try_again_later” (or something similar). The route handlers have a shared state which is an Arc<Mutex<()>>
. Once a handler uses the camera it uses try_block()
on the Mutex. If the result is Ok
it uses the camera, if it’s an Err
it returns “resource_busy”.
This is the method that works, but I am confused, because I don’t know why exactly. It’s rather by accident that I found a working solution. I also tried RwLock (both the std and tokio versions), but they didn’t work either (they would block everything, maybe makeing a deadlock, but I am not exactly sure). Before I had a bool
to signal if the resource is busy (Arc<Mutex<bool>>
) and used it with lock().await
. If the contained bool was true I would use the camera, if false I would return resource_busy
. This didn’t work as the thread (or async_function) would apparently wait till it can lock the resource and only then use the camera. Basically this would create a queue.
A Mutex from std::sync would also not work as it is not Send
.
The Mutex from tokio works a slightly differently apparently, but the documentation is a quite dense for someone new to async/concurrent programming.
I would like to know if my solution (the “empty” Mutex together with try_lock()
) is a sensible solution or an idiomatic one and why? If not, what would be a better way to solve this?
It appears to me that a lot of “normal” use-cases when using Arcs, Mutexes, assume that a resource is only locked for a fraction of a second and are more concerned about order of execution or something like that. But in my case the resource is busy for quite a long time (and if I use the try_lock()
-solution it’s also locked for a long time). It would feel cleaner to only lock the mutex in order to set the contained bool to true
(resource is busy) before freeing it again and starting the camera operation.