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

Add disconnected flavor which immediately fails #1047

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ryoqun
Copy link
Contributor

@ryoqun ryoqun commented Dec 8, 2023

Yet another small niceties, i'd like to add to crossbeam_channel.

This doesn't look meaningful by itself at first glance. However, this is useful for conditionally inserting an artificial select arm at predetermined priority in the select_biased!() #1040, combined with never() like this:

select_biased! {
    recv(important_channel) -> urgent_message => {
        ...
    },
    recv(if is_local_task_available { disconnected() } else { never() }) -> _dummy_signal => {
        ...
    },
    recv(normal_channel) -> normal_message => {
        ...
    },
}

Note that using tick() like below introduces needless calls to Instant::now() (which is a vdso basically) per select invocation on top of the needless stack memory consumption. (On the other hand, the zst & const-code-heavy disconnected() will be optimized out to great degree after the macro expansion)..:

fn always() -> Receiver<Instant> {
    tick(Duration::default())
}

Also, unrolling the select is possible, but creates code duplication. Lastly, checking is_local_task_available after select_biased!() alone would introduce a priority inversion.

Thus, i think there's no acceptable alternative solution currently.

@@ -274,6 +274,13 @@ pub fn never<T>() -> Receiver<T> {
}
}

/// Creates a receiver that is disconnected always.
Copy link
Contributor Author

@ryoqun ryoqun Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to expand this doccomment with an example, which will be based on the one in the pr description with polishes, once it's confirmed that this pr has some hope to be merged.

}

impl<T> Channel<T> {
/// Creates a channel that always delivers messages.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops forgot to update..

@taiki-e
Copy link
Member

taiki-e commented Dec 21, 2023

Thanks for the PR. I guess this could be replaced by never + disconnect once the API for explicit disconnection is exposed?

@ryoqun
Copy link
Contributor Author

ryoqun commented Dec 22, 2023

Thanks for the PR. I guess this could be replaced by never + disconnect once the API for explicit disconnection is exposed?

hey, really thanks for replying!

yeah, assuming the disconnected never is implemented in a hard-coded way without any state much like the never itself for maximum optimization opportunity by rustc.

note that the tick approach in the pr description or just let disconnected = unbounded().1 would work much like disconnected(). however the two approaches introduce some overhead, which i'd like to avoid entirely.

@ryoqun
Copy link
Contributor Author

ryoqun commented Jan 4, 2024

i think disconnected dummy sender might also be useful. ref: #750

how about this api? let (sender, receiver) = disconnected()? (i.e. align with unbounded() and bounded(...))

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

Successfully merging this pull request may close these issues.

2 participants