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

Idea: channel_match! macro #35

Open
ranaya-formant opened this issue Sep 2, 2020 · 6 comments
Open

Idea: channel_match! macro #35

ranaya-formant opened this issue Sep 2, 2020 · 6 comments

Comments

@ranaya-formant
Copy link

ranaya-formant commented Sep 2, 2020

channel_match!(
   rx => |x:X| println!("{}",x)
   rx => |y:Y| println!("{}",y)
)
enum SelectMatch2<Q,S>{
   A(Q)
   B(S)
}
...

{
let a = |x:X| println!("{}",x)
let b =  |y:Y|1 println!("{}",y)
let result = flume::Selector::new()
    .recv(&rx0, |x| SelectMatch2<X,Y>::A(x) )
    .recv(&rx1, |x| SelectMatch2<X,Y>::B(x) )
    .wait();
match x 
   SelectMatch2<X,Y>::A(x) => a(x),
   SelectMatch2<X,Y>::B(x) => b(x),
};
}

There might be some generic magic I don't know about that could make this even simpler.

@zesterer
Copy link
Owner

zesterer commented Sep 2, 2020

Macros aren't usually my thing, but I'll give it a go tonight!

@LukasKalbertodt
Copy link

It would be great if flume could offer a macro that is not based on Selector and closures. A common use case is to return, break or continue in response to one channel being selected. This is not possible in a closure. Closures also make ? a bit more difficult to use.

I just switched from crossbream-channel to flume and rewriting those crossbeam_channel::select! invocations was not particularly nice. I basically ended up creating a custom enum Action for each selection. Then I have let action = Selector::new()....wait(); immediately followed by a match action where the actual work is being done.

Another reason against closures is that borrowing get's easier. If two recv closures need mutable access to a variable... well, it's not possible. With crossbeam's select it is.

That said, I have no idea how selection is even implemented and how crossbeam's select works. So this might be a lot of work. With macros I could help, however.

@zesterer
Copy link
Owner

zesterer commented Sep 23, 2020

@LukasKalbertodt I'm planning to work on this at some point. In the meantime, you can use an enum to get the same behaviour like this (note: I think that crossbeam does something similar to this, but generated automatically):

enum Selection<A, B, C> {
    A(A),
    B(B),
    C(C),
}

match Selector::new()
    .recv(&my_recv, Selection::A)
    .send(&my_send, Selection::B)
    .recv(&my_recv2, Selection::C)
    .wait()
{
    Selection::A(a) => ...,
    Selection::B(b) => ...,
    Selection::C(c) => ...,
}

It's recently come to our attention, via #44 , that there may be a race condition in the selector code that causes it to hang in some specific circumstances (it might also just be a malfunctioning test). I'm going to try to find the time to address this over the next week but it's something to be aware of.

@zesterer
Copy link
Owner

To add to the topic of this issue in general: I spent a few hours last week writing a macro for this. It's not finished yet, but I have had some success.

@Restioson
Copy link
Collaborator

I wonder how this interacts with #39 for select macros in loops.

@zesterer
Copy link
Owner

@Restioson I think the key is probably to reduce the cost of construction of Selector.

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

No branches or pull requests

4 participants