Is This Deadlocked?

Hi, I have some code here for a websocket server using warp.

I seems like this line is where my code just stops... Quacker-Backs/ws-server/src/quackers_game_logic/client_msg_handler.rs at main · JimLynchCodes/Quacker-Backs · GitHub

I am wondering if it is because I am calling clients.lock too much.

I can see the log statement from line 192 printed in my console when I'm running the server locally, but it never gets to line 198...

I want to keep this Mutex list of connected clients, and when I need to "blast a message" it seems like I need to have a mutable reference to each client. But I am also saving other data for my game like player x and y position which I need to mutate... maybe having a two different hashmaps, each with client uuid as the key would solve my problems here? Or should I move some of the matches inside out of each other?

I know this code is kind of messy but curious for advice on how to get this working / efficient / elegantly written. Thanks :cowboy_hat_face:

Holy nesting batman! :joy:

I could be wrong, but you've shadowed client_lock and that seems like either a mistake or at least is questionable/error prone.

Shadowing can be idiomatic when you're inside a small function and are converting types, but this is different.

Also, functions! Please use more of them.

2 Likes

Does current_sender.send block when a message queue is backlogged? (not looked as deep into code to see type, but seems a likely candidate.)

Thanks for the replies. :slight_smile: :+1:

I still don't really fully know what's happening with clients.lock().await

There is no .unlock function on the mutext guard... so is that just handled automatically by Rust? The way I'm understanding it is that as soon as you get to the closing curly brace that ends the scope where you created the mutext guard then it will be unlocked and therefore available to be locked again... but is that how it actually works?

Yes, it is unlocked when the lock guard is dropped.

2 Likes

Now I'm doing something like this. Not sure if I really needed to split out the sender into its own hashmap, but the message handler function does seem a lot easier to follow now I think. :+1:

pub async fn client_msg(
    client_id: &str,
    msg: Message,
    client_connections_arc_mutex: &ClientConnections,
    client_data_arc_mutex: &ClientsGameData,
    cracker: &Cracker,
) {
    println!("received message from {}: {:?}", client_id, msg);
    
    let json_message = unpack_message(msg);

    let action_type = get_action_type_from_message(json_message);

    match action_type {
        IncomingGameActionType::SubmitName => handle_submit_name_action(),
        IncomingGameActionType::PlayerMove => handle_move_action(),
        IncomingGameActionType::Quack => handle_quack_action(),
        IncomingGameActionType::Empty => (),
    }
}
1 Like