rust-socketio icon indicating copy to clipboard operation
rust-socketio copied to clipboard

fix: deadlock on recursive emit_with_ack calls

Open bastilimbach opened this issue 1 year ago • 0 comments

Hi @1c3t3a, I came across an issue while trying to call emit_with_ack recursively like so:

socket
        .emit_with_ack(
            "event_with_ack",
            json!({"event_with_ack": "first call"}),
            Duration::from_secs(20000),
            move |data, s| {
                println!("Ack 1 received: {:#?}", data);

                // This works
                s.emit("event", json!({"event": "second call"}))
                    .expect("Server unreachable");

                // This doesn't work due to deadlock on "outstanding_acks" in emit_with_ack(). The callback is never executed.
                s.emit_with_ack(
                    "event_with_ack",
                    json!({"event_with_ack": "second call"}),
                    Duration::from_secs(20000),
                    |data, _| {
                        println!("Ack 2 received: {:#?}", data);
                    },
                )
                .expect("Server unreachable");
            },
        )
        .expect("Server unreachable");

I noticed that the second callback is never executed, and the program just waits indefinitely. After some quick debugging, I drilled down the problem to a deadlock of self.outstanding_acks in the RawClient.

Steps to reproduce

I created a minimal example which can be used to reproduce the issue: https://github.com/bastilimbach/rust-socketio-deadlock

The steps are written in the README.

Remarks

I'm quite new to Rust and would appreciate any requests to changes, etc. Also, I wasn't sure how to write tests for this. I could create a test which calls emit_with_ack recursively and call it a day but I'm not sure if this is really the way to go here. Looking forward to suggestions!

bastilimbach avatar Sep 26 '24 09:09 bastilimbach