Skip to content

File Descriptor Leak in Producer #287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tgockel opened this issue Apr 28, 2025 · 1 comment
Open

File Descriptor Leak in Producer #287

tgockel opened this issue Apr 28, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@tgockel
Copy link
Contributor

tgockel commented Apr 28, 2025

Describe the bug

When you create a Producer and drop it, the underlying connection remains open, even though there are no references to the producer.

Reproduction steps

This is most easily reproduced with a unit test and observation with ss. First, add this test (e.g.: test/producer_test.rs):

#[tokio::test(flavor = "multi_thread")]
async fn connect_and_drop() {
    let env = TestEnvironment::create().await;
    for count in 0..1000 {
        println!("{count}...");
        let producer = env.env.producer().build(&env.stream).await.unwrap();
        drop(producer);
        tokio::time::sleep(Duration::from_millis(50)).await;
    }

    println!("All connections dropped, waiting 10 seconds...");
    tokio::time::sleep(Duration::from_secs(10)).await;
}
  1. Start the RabbitMQ server with make rabbitmq-server
  2. Watch the connection list with sudo nsenter -t $(docker inspect -f '{{.State.Pid}}' rabbitmq-tls-test) watch ss -anut
  3. Run cargo test -- --nocapture connect_and_drop
  4. Watch the thing you created in step 2 for a bunch of tcp ESTAB connections to be added but never dropped

Expected behavior

What should happen here is, since we're immediately calling drop(producer), there should be a graceful termination of the TCP connection. Instead, the connection for these producers stay in the established state as long as the process is running. If you SIGINT the process, the connections on the server side will go into the TIME-WAIT as the connections are non-gracefully dropped.

Leaving the client running will eventually cause EBUSY, as there are too many open connections:

thread 'connect_and_drop' panicked at tests/./common.rs:143:64:
called `Result::unwrap()` on an `Err` value: Client(Io(Os { code: 16, kind: ResourceBusy, message: "Device or resource busy" }))

Additional context

This is probably not a huge deal, since most usage is connecting once and going from there.

@tgockel tgockel added the bug Something isn't working label Apr 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant