Skip to content
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

Async channel is blocking program #5

Closed
szagi3891 opened this issue Jan 11, 2016 · 9 comments
Closed

Async channel is blocking program #5

szagi3891 opened this issue Jan 11, 2016 · 9 comments
Labels

Comments

@szagi3891
Copy link

I use channel createt widh chan::async.
In my laptop perfect working. On my second computer blocks when sending function data using chan::Sender.

It looks like a bug. Please help :)

@BurntSushi
Copy link
Owner

Could you please provide a minimal code example that reproduces the bug?

Please provide as many details as possible, otherwise it's hard to help you.

@szagi3891
Copy link
Author

Can I give you a link to the entire repository? ( https://github.com/szagi3891/testhttp , branch "process")

In the evening I will try to extract a small piece of code.

@BurntSushi
Copy link
Owner

I really don't have the time to be looking through an entire repository of code. If there's a bug in chan, then I'd really prefer to see a small piece of code that I can run that reproduces the problem you're experiencing.

@szagi3891
Copy link
Author

Sure. In the evening I will try to prepare a small piece of code.

@szagi3891
Copy link
Author

I create test repo width minimal code.
Enough to do :

git clone https://github.com/szagi3891/test_chan_bug
cd test_chan_bug
cargo run

I get output :

grzegorz@grzegorz:~/Pulpit/rust/testchan$ cargo run
     Running `target/debug/testchan`
Hello, world!
before send
^CTermination signal catched.

grzegorz@grzegorz:~/Pulpit/rust/testchan$ Shutting down!

grzegorz@grzegorz:~/Pulpit/rust/testchan$ 
grzegorz@grzegorz:~/Pulpit/rust/testchan$ cargo run
     Running `target/debug/testchan`
Hello, world!
before send
worker 1: get value rx_request Some("simple value1")
^CTermination signal catched.
grzegorz@grzegorz:~/Pulpit/rust/testchan$ ./target/debug/testchan 
Hello, world!
before send
^CTermination signal catched.
Shutting down!
grzegorz@grzegorz:~/Pulpit/rust/testchan$ ./target/debug/testchan 
Hello, world!
before send
^CTermination signal catched.
Shutting down!
grzegorz@grzegorz:~/Pulpit/rust/testchan$ 
grzegorz@grzegorz:~/Pulpit/rust/testchan$ 
grzegorz@grzegorz:~/Pulpit/rust/testchan$ ./target/debug/testchan 
Hello, world!
before send
^CTermination signal catched.
Shutting down!
grzegorz@grzegorz:~/Pulpit/rust/testchan$ 
grzegorz@grzegorz:~/Pulpit/rust/testchan$ 
grzegorz@grzegorz:~/Pulpit/rust/testchan$ ./target/debug/testchan 
Hello, world!
before send
worker 9: get value rx_request Some("simple value1")
worker 7: get value rx_request Some("simple value2")
after send
before send
^CTermination signal catched.
Shutting down!
grzegorz@grzegorz:~/Pulpit/rust/testchan$

Code stops when we pass the data on channel tx_request.
Sender should never pause because the channel is asynchronous.

            println!("before send");
            tx_request.send("simple value1");
            tx_request.send("simple value2");
            tx_request.send("simple value3");
            println!("after send");

@szagi3891
Copy link
Author

description is good? I left only a small piece of code that deals with the problem.

@BurntSushi
Copy link
Owner

@szagi3891 Yes, thank you! I was able to trim it down to this:

#[macro_use]
extern crate chan;

use std::io;
use std::thread::{self, JoinHandle};
use std::time::Duration;

fn main() {
    println!("Hello, world!");

    let (send1, recv1) = chan::async();

    thread::spawn(move || {
        loop {
            println!("before send");
            send1.send("simple value1");
            send1.send("simple value2");
            send1.send("simple value3");
            println!("after send");

            thread::sleep(Duration::from_millis(50));
        }
    });

    let (_send2, recv2) = chan::async::<String>();

    for i in 0..30 {
        let recv1 = recv1.clone();
        let recv2 = recv2.clone();

        spawn(format!("worker {}", i), move || {
            println!("starting worker {}", i);
            loop {
                chan_select! {
                    recv1.recv() -> val => {
                        println!("worker {}: get value recv1 {:?}", i, val);
                    },
                    recv2.recv() -> val => {
                        println!("worker {}: get value recv2 {:?}", i, val);
                    }
                }
            }
        }).unwrap();
    }
    chan_select! {}
}

fn spawn<F, T>(name: String, block: F) -> io::Result<JoinHandle<T>>
    where F: FnOnce() -> T + Send + 'static, T: Send + 'static {

    thread::Builder::new().name(name).spawn(block)
}

My thinking right now is that it probably is indeed a bug. My guess is that chan_select! is for some reason not releasing a lock that all channels must acquire when sending values.

For what it's worth, I would, in general, recommend using synchronous channels, with a buffer if needed. (That doesn't help in this case though, since it looks like synchronous channels are affected too.)

@BurntSushi BurntSushi added the bug label Jan 14, 2016
@szagi3891
Copy link
Author

Thank you. And is there a chance that it will somehow fix soon?

@szagi3891
Copy link
Author

Clever amendment :)

I did own implementation channels (no macro select).
https://github.com/szagi3891/channels_async-rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants