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

fix(iroh): get rid of flume channels #2536

Closed
wants to merge 10 commits into from
Closed

fix(iroh): get rid of flume channels #2536

wants to merge 10 commits into from

Conversation

rklaehn
Copy link
Contributor

@rklaehn rklaehn commented Jul 23, 2024

Description

Get rid of flume channels

I am doing this as multiple PRs

Flume channels have a bug?(*) regarding notifications when the futures returned by recv_async are cancelled. Reproducer here: https://github.com/rklaehn/flume-bug-reproducer . Note that this does not lead to loss of messages, but loss of notifications.

(it is unclear what guarantees regarding cancel safety flume gives at all... See zesterer/flume#104 )

If you have another future like a regular timer that resolves frequently, you will never see the issue. But if you have something like an actor where the flume channel is the only source of regular events, you might be "stuck" until somebody sends another message.

So in every single location where we use select! with one of the cases being recv_async, there is a small potential to lose notifications.

Given that we use select! a lot, I think we can't afford to carefully study every single case. Replacing the select! with code that merges streams also does not seem to be a viable option.

So the only remaining option is to change to an async mpmc channel that is experimentally shown to be safe against cancellation. The only one I found is async_channel. When using async_channel in the reproducer above, the bug immediately goes away.

Breaking Changes

None

Notes & open questions

Other options?
Benchmarks?
Remove the unsafe same_channel workaround or keep it for now?

Change checklist

  • Self-review.
  • Documentation updates following the style guide, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

rklaehn added a commit that referenced this pull request Jul 24, 2024
rklaehn added a commit that referenced this pull request Jul 24, 2024
rklaehn added a commit that referenced this pull request Jul 24, 2024
rklaehn added a commit that referenced this pull request Jul 24, 2024
github-merge-queue bot pushed a commit that referenced this pull request Jul 24, 2024
## Description

refactor(iroh-net): replace flume in iroh-net with async_channel

Rationale: see #2536

This is the first in a series of PRs that will replace flume with
async_channel. In this case it is very close to a drop in replacement
without any need for changes.

Only noteable changes:

send_async becomes send
send becomes send_blocking
Receiver implements Stream, so no need for .into_stream()
Receiver is not Unpin, so to make it unpin you need to do
`Box::pin(recv)` or use `.boxed()`

## Breaking Changes

None

## Notes & open questions

- Anything specific from flume we were relying on here?

## Change checklist

- [x] Self-review.
- [x] ~~Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.~~
- [x] ~~Tests if relevant.~~
- [x] ~~All breaking changes documented.~~
@dignifiedquire dignifiedquire added this to the v0.22.0 milestone Jul 29, 2024
Copy link

github-actions bot commented Aug 1, 2024

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/2536/docs/iroh/

Last updated: 2024-08-05T12:08:31Z

@dignifiedquire
Copy link
Contributor

Now all usage of flume in the repo are gone. The only missing thing is a blocking recv_timeout

@dignifiedquire dignifiedquire modified the milestones: v0.22.0, v0.23.0 Aug 5, 2024
@rklaehn
Copy link
Contributor Author

rklaehn commented Aug 14, 2024

We still have the dependency via quic-rpc, but other than that we are flume-free. So I am going to close this.

@rklaehn rklaehn closed this Aug 14, 2024
rklaehn added a commit to n0-computer/iroh-blobs that referenced this pull request Oct 22, 2024
## Description

refactor(iroh-net): replace flume in iroh-net with async_channel

Rationale: see n0-computer/iroh#2536

This is the first in a series of PRs that will replace flume with
async_channel. In this case it is very close to a drop in replacement
without any need for changes.

Only noteable changes:

send_async becomes send
send becomes send_blocking
Receiver implements Stream, so no need for .into_stream()
Receiver is not Unpin, so to make it unpin you need to do
`Box::pin(recv)` or use `.boxed()`

## Breaking Changes

None

## Notes & open questions

- Anything specific from flume we were relying on here?

## Change checklist

- [x] Self-review.
- [x] ~~Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.~~
- [x] ~~Tests if relevant.~~
- [x] ~~All breaking changes documented.~~
rklaehn added a commit to n0-computer/iroh-blobs that referenced this pull request Oct 22, 2024
## Description

refactor(iroh-net): replace flume in iroh-net with async_channel

Rationale: see n0-computer/iroh#2536

This is the first in a series of PRs that will replace flume with
async_channel. In this case it is very close to a drop in replacement
without any need for changes.

Only noteable changes:

send_async becomes send
send becomes send_blocking
Receiver implements Stream, so no need for .into_stream()
Receiver is not Unpin, so to make it unpin you need to do
`Box::pin(recv)` or use `.boxed()`

## Breaking Changes

None

## Notes & open questions

- Anything specific from flume we were relying on here?

## Change checklist

- [x] Self-review.
- [x] ~~Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.~~
- [x] ~~Tests if relevant.~~
- [x] ~~All breaking changes documented.~~
matheus23 pushed a commit to n0-computer/iroh-doctor that referenced this pull request Oct 22, 2024
## Description

refactor(iroh-net): replace flume in iroh-net with async_channel

Rationale: see n0-computer/iroh#2536

This is the first in a series of PRs that will replace flume with
async_channel. In this case it is very close to a drop in replacement
without any need for changes.

Only noteable changes:

send_async becomes send
send becomes send_blocking
Receiver implements Stream, so no need for .into_stream()
Receiver is not Unpin, so to make it unpin you need to do
`Box::pin(recv)` or use `.boxed()`

## Breaking Changes

None

## Notes & open questions

- Anything specific from flume we were relying on here?

## Change checklist

- [x] Self-review.
- [x] ~~Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.~~
- [x] ~~Tests if relevant.~~
- [x] ~~All breaking changes documented.~~
matheus23 pushed a commit that referenced this pull request Nov 14, 2024
## Description

refactor(iroh-net): replace flume in iroh-net with async_channel

Rationale: see #2536

This is the first in a series of PRs that will replace flume with
async_channel. In this case it is very close to a drop in replacement
without any need for changes.

Only noteable changes:

send_async becomes send
send becomes send_blocking
Receiver implements Stream, so no need for .into_stream()
Receiver is not Unpin, so to make it unpin you need to do
`Box::pin(recv)` or use `.boxed()`

## Breaking Changes

None

## Notes & open questions

- Anything specific from flume we were relying on here?

## Change checklist

- [x] Self-review.
- [x] ~~Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.~~
- [x] ~~Tests if relevant.~~
- [x] ~~All breaking changes documented.~~
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants