coap-rs icon indicating copy to clipboard operation
coap-rs copied to clipboard

Shortcoming in documentation on shared state when running a server

Open Teufelchen1 opened this issue 1 year ago • 5 comments

Hi,

I find this to be unclear and hard to use. This might be an area where increased documentation or an example might be needed https://github.com/Covertness/coap-rs/blob/c1201466f385c7e69608641f935ae0378850401f/src/server.rs#L74-L81

Teufelchen1 avatar Jun 20 '24 15:06 Teufelchen1

Ah, I might have been a bit short on the exact issue here, let me give an naive example. Imagine having this code within you main(){}:

let addr = "127.0.0.1:5683";
    Runtime::new().unwrap().block_on(async move {
         let server = Server::new_udp(addr).unwrap();
         println!("Server up on {}", addr);

         server.run(handle_request).await.unwrap();
     });

Outside of the main scope, you would define the handle_request function:

async fn handle_request<'a,'async_trait>(mut request: Box<CoapRequest<SocketAddr>>) -> Box<CoapRequest<std::net::SocketAddr>>{
             match request.get_method() {
                 &Method::Post => {
                    match request.get_path().as_str() {
                        "input/" => {
                            /* do your Application Logic */
                        }
                        _ => {
                            println!("request by post {}", request.get_path());
                        }
                    };
                 },
                 _ => println!("request by other method"),
             };

             match request.response {
                 Some(ref mut message) => {
                     message.message.payload = b"OK".to_vec();

                 },
                 _ => {}
             };
             return request
}

Now, the issue with the documentation is, that this should be enough to handle external state. But how exactly would one do that? I think that is not obvious for Rust newcomers.

Teufelchen1 avatar Jun 20 '24 15:06 Teufelchen1

You can define the handle_request function inside the main scope. The closure can be used to share state.

Covertness avatar Jun 22 '24 06:06 Covertness

Hm. I tried doing that but failed to achieve something useful. I don't want to derail this issue to be a Rust tutorial - if you think that it is still related enough to this crate: Could you give me an example how you would have shared state with the closure? If you point me in the right direction I could try to build a second example and PR' it into this repo.

Teufelchen1 avatar Jun 25 '24 08:06 Teufelchen1

the general naive answer is to have an Arc<Mutex<SharedState>> if you have some state you want to modify in each request. You can use tokio's Mutex if you plan on holding the mutex over an await. You can also try a RwLock if you want to squeeze more performance out of it

This is really an in-between solution, it would be great to have a Resource trait that can registered independently.

osobiehl avatar Jun 25 '24 10:06 osobiehl

@osobiehl is right. There are many articles about it. e.g. https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/second-edition/ch16-03-shared-state.html

But share state has many disadvantages in a concurrency world. I like to use the meesage when need to share information.

Covertness avatar Jun 25 '24 13:06 Covertness

Closed. Reopen it if you have any new problem about it.

Covertness avatar Sep 04 '24 15:09 Covertness