These are chat archives for rust-lang/rust

17th
Feb 2018
Michal 'vorner' Vaner
@vorner
Feb 17 2018 08:17

Hello. Let's say I have a code like this:

let threads = (0..10).map(|| thread::spawn(do_some_work)).collect::<Vec<_>>();
for t in threads {
  t.join().unwrap();
}

This works, but it has one downside. If one of the threads panics, the application continues until all the others are done. Is there a similar pattern if I want to know at once that a thread has panicked and do something about it (eg. not panic = abort compilation)?

Aleksey Kladov
@matklad
Feb 17 2018 08:20
@vorner each thread can send a message into a channel upon completion, and then select over the set of channels.
I am not sure if one can get notification about channels close event. If it's not possible, then a raii wrapper that sends a message in Drop might help
Michal 'vorner' Vaner
@vorner
Feb 17 2018 08:21
@matklad Is there channel selection in stable rust already?
Aleksey Kladov
@matklad
Feb 17 2018 08:22
@vorner nope, and it's unlikely that it will be available. Any reason why you can't use https://docs.rs/crossbeam-channel/0.1.2?
btw, I've just checked, you do get a notification when the sending half is closed: https://docs.rs/crossbeam-channel/0.1.2/crossbeam_channel/struct.RecvError.html
Michal 'vorner' Vaner
@vorner
Feb 17 2018 08:24
No, not really. I just kind of expected the std to handle a use case where I don't want half of my application to keep running when part fails (I recently read a bunch of Go code that suffered from this a lot, so I wondered how Rust handles that).
Aleksey Kladov
@matklad
Feb 17 2018 08:28
Yeah, I believe one can't select on the JoinHandlers, so some channel-based solution is required. And it seems to be true that std channels don't receive a lot of attention right now, instead the development is focused on crates.io crates.
Daniel Bischof
@dbischof90
Feb 17 2018 11:16
What's the downside of unbounded channels?
Denis Lisov
@tanriol
Feb 17 2018 11:19
@dbischof90 If your sender is faster than receiver, a bounded channel will force the sender to slow down, while an unbounded one will just grow its memory consumption resulting in out-of-memory and/or radical slowdown when nearly out of memory.
Also, if you're doing something interactive, the processing latency increases roughly proportional to the queue length.
Daniel Bischof
@dbischof90
Feb 17 2018 11:51
I see.
Daniel Bischof
@dbischof90
Feb 17 2018 11:56
What about a data source that is consistently faster? How would a bounded channel react? Block the sending thread?
Denis Lisov
@tanriol
Feb 17 2018 11:57
For std channels, yes, block the thread.
Daniel Bischof
@dbischof90
Feb 17 2018 16:20
Where would you see (dis-)advantages between crossbeam and futures::mpsc if you needed a single consumer only? The futures crate seems to be rather confusing.
Denis Lisov
@tanriol
Feb 17 2018 16:21
I'd use futures if my problem is async, but not in sync cases. If you could describe your problem, someone could give you a better advice :-)
Nicolas Almy
@almynic
Feb 17 2018 17:00

Somehow I don't get borrowing. How do i make this prints what is commented on the println
`

let s1 = String::from("hello");
let mut s2 = &s1; // borrow s1 

println!("{}", s1); // print hello
println!("{}", s2); // print hello
s2 = &String::from("world");

println!("{}", s1); // world 
println!("{}", s2); // world

```

I'm off cooking, wont be back for a little while
Denis Lisov
@tanriol
Feb 17 2018 17:13
@almynic This is nontrivial and requires internal mutability. You want to be able to look into s1 while a mutable reference to it s2 exists (it can't be immutable as you want to change s1 through it). This violates Rust's borrowing rules. Are you really sure you need this?
Andy Grove
@andygrove
Feb 17 2018 17:34
So I'm refactoring some code to change a "Value" type from an enum to a trait and overall it is going well but I've just hit a problem ... I can't have my Value trait inherit from serde::Serialize because "method serialize has generic type parameters" and therefore I can no longer use Value as a trait object
I'm not sure how to handle this.
Denis Lisov
@tanriol
Feb 17 2018 17:36
@andygrove erased-serde?
Not sure of the performance implications, however.
Daniel Bischof
@dbischof90
Feb 17 2018 17:37
Well.. let's say I have a main thread M which acts kind of as an reception. It has a TCP port that it listens on and gets something like JSON objects there. Those are resolved by one of several very specific threads, A, B, etc. Each thread has a (unique) function and a database handler that writes a result to a DB. I plan to encapsulate the database work into a future - it's more important that the time between the TCP gate and the function execution inside of A, B, etc. is short. The DB can take as long as it needs to. @tanriol
Andy Grove
@andygrove
Feb 17 2018 17:37
oh wow, thanks!
another very similar issue is that I'd like Value to extend Clone as well
but "the trait cannot require that Self : Sized"
Denis Lisov
@tanriol
Feb 17 2018 17:45
@dbischof90 If you want to run futures on these threads, you should be using the futures channels. However, you can also offload the DB work to a separate set of threads.
@dbischof90 Given this architecture description, I'd actually try actix or something like that.
Daniel Bischof
@dbischof90
Feb 17 2018 17:49
Yes, I have futures-cpupool or something like that noted down somewhere.
That sounds indeed intriguing!
I wanted to take the tokio/futures route first though. actix seems to be built on top of tokio anyways but I think understanding the elements a little better (before I refactor it with actix potentially) might be a better idea
Denis Lisov
@tanriol
Feb 17 2018 18:04
@andygrove My best try is something like this