Skip to content

Commit b0082bc

Browse files
committed
Replace flume with async_channel in docs
This is mostly a 1:1 replacement, except for the fact that the same_channel api is missing from async_channel. So I replaced it with some ugly code that uses the fact that a async_channel Sender or Receiver is just an Arc<Channel>. To be removed if/when smol-rs/async-channel#98 is merged, but until then I think it is fine.
1 parent 9052905 commit b0082bc

File tree

6 files changed

+81
-57
lines changed

6 files changed

+81
-57
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

iroh-docs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ workspace = true
1616

1717
[dependencies]
1818
anyhow = "1"
19+
async-channel = "2.3.1"
1920
blake3 = { package = "iroh-blake3", version = "1.4.5"}
2021
bytes = { version = "1.4", features = ["serde"] }
2122
derive_more = { version = "1.0.0-beta.6", features = ["debug", "deref", "display", "from", "try_into", "into", "as_ref"] }
2223
ed25519-dalek = { version = "2.0.0", features = ["serde", "rand_core"] }
23-
flume = "0.11"
2424
futures-buffered = "0.2.4"
2525
futures-lite = "2.3.0"
2626
futures-util = { version = "0.3.25" }

iroh-docs/src/actor.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ enum Action {
6161
#[display("ListAuthors")]
6262
ListAuthors {
6363
#[debug("reply")]
64-
reply: flume::Sender<Result<AuthorId>>,
64+
reply: async_channel::Sender<Result<AuthorId>>,
6565
},
6666
#[display("ListReplicas")]
6767
ListReplicas {
6868
#[debug("reply")]
69-
reply: flume::Sender<Result<(NamespaceId, CapabilityKind)>>,
69+
reply: async_channel::Sender<Result<(NamespaceId, CapabilityKind)>>,
7070
},
7171
#[display("ContentHashes")]
7272
ContentHashes {
@@ -108,12 +108,12 @@ enum ReplicaAction {
108108
reply: oneshot::Sender<Result<()>>,
109109
},
110110
Subscribe {
111-
sender: flume::Sender<Event>,
111+
sender: async_channel::Sender<Event>,
112112
#[debug("reply")]
113113
reply: oneshot::Sender<Result<()>>,
114114
},
115115
Unsubscribe {
116-
sender: flume::Sender<Event>,
116+
sender: async_channel::Sender<Event>,
117117
#[debug("reply")]
118118
reply: oneshot::Sender<Result<()>>,
119119
},
@@ -166,7 +166,7 @@ enum ReplicaAction {
166166
},
167167
GetMany {
168168
query: Query,
169-
reply: flume::Sender<Result<SignedEntry>>,
169+
reply: async_channel::Sender<Result<SignedEntry>>,
170170
},
171171
DropReplica {
172172
reply: oneshot::Sender<Result<()>>,
@@ -222,7 +222,7 @@ struct OpenReplica {
222222
/// [`SyncHandle::drop`] will not block.
223223
#[derive(Debug, Clone)]
224224
pub struct SyncHandle {
225-
tx: flume::Sender<Action>,
225+
tx: async_channel::Sender<Action>,
226226
join_handle: Arc<Option<JoinHandle<()>>>,
227227
}
228228

@@ -232,7 +232,7 @@ pub struct OpenOpts {
232232
/// Set to true to set sync state to true.
233233
pub sync: bool,
234234
/// Optionally subscribe to replica events.
235-
pub subscribe: Option<flume::Sender<Event>>,
235+
pub subscribe: Option<async_channel::Sender<Event>>,
236236
}
237237
impl OpenOpts {
238238
/// Set sync state to true.
@@ -241,7 +241,7 @@ impl OpenOpts {
241241
self
242242
}
243243
/// Subscribe to replica events.
244-
pub fn subscribe(mut self, subscribe: flume::Sender<Event>) -> Self {
244+
pub fn subscribe(mut self, subscribe: async_channel::Sender<Event>) -> Self {
245245
self.subscribe = Some(subscribe);
246246
self
247247
}
@@ -255,7 +255,7 @@ impl SyncHandle {
255255
content_status_callback: Option<ContentStatusCallback>,
256256
me: String,
257257
) -> SyncHandle {
258-
let (action_tx, action_rx) = flume::bounded(ACTION_CAP);
258+
let (action_tx, action_rx) = async_channel::bounded(ACTION_CAP);
259259
let actor = Actor {
260260
store,
261261
states: Default::default(),
@@ -298,7 +298,7 @@ impl SyncHandle {
298298
pub async fn subscribe(
299299
&self,
300300
namespace: NamespaceId,
301-
sender: flume::Sender<Event>,
301+
sender: async_channel::Sender<Event>,
302302
) -> Result<()> {
303303
let (reply, rx) = oneshot::channel();
304304
self.send_replica(namespace, ReplicaAction::Subscribe { sender, reply })
@@ -309,7 +309,7 @@ impl SyncHandle {
309309
pub async fn unsubscribe(
310310
&self,
311311
namespace: NamespaceId,
312-
sender: flume::Sender<Event>,
312+
sender: async_channel::Sender<Event>,
313313
) -> Result<()> {
314314
let (reply, rx) = oneshot::channel();
315315
self.send_replica(namespace, ReplicaAction::Unsubscribe { sender, reply })
@@ -435,7 +435,7 @@ impl SyncHandle {
435435
&self,
436436
namespace: NamespaceId,
437437
query: Query,
438-
reply: flume::Sender<Result<SignedEntry>>,
438+
reply: async_channel::Sender<Result<SignedEntry>>,
439439
) -> Result<()> {
440440
let action = ReplicaAction::GetMany { query, reply };
441441
self.send_replica(namespace, action).await?;
@@ -489,13 +489,13 @@ impl SyncHandle {
489489
Ok(store)
490490
}
491491

492-
pub async fn list_authors(&self, reply: flume::Sender<Result<AuthorId>>) -> Result<()> {
492+
pub async fn list_authors(&self, reply: async_channel::Sender<Result<AuthorId>>) -> Result<()> {
493493
self.send(Action::ListAuthors { reply }).await
494494
}
495495

496496
pub async fn list_replicas(
497497
&self,
498-
reply: flume::Sender<Result<(NamespaceId, CapabilityKind)>>,
498+
reply: async_channel::Sender<Result<(NamespaceId, CapabilityKind)>>,
499499
) -> Result<()> {
500500
self.send(Action::ListReplicas { reply }).await
501501
}
@@ -566,7 +566,7 @@ impl SyncHandle {
566566

567567
async fn send(&self, action: Action) -> Result<()> {
568568
self.tx
569-
.send_async(action)
569+
.send(action)
570570
.await
571571
.context("sending to iroh_docs actor failed")?;
572572
Ok(())
@@ -581,7 +581,10 @@ impl Drop for SyncHandle {
581581
fn drop(&mut self) {
582582
// this means we're dropping the last reference
583583
if let Some(handle) = Arc::get_mut(&mut self.join_handle) {
584-
self.tx.send(Action::Shutdown { reply: None }).ok();
584+
// this call is the reason tx can not be a tokio mpsc channel.
585+
// we have no control about where drop is called, yet tokio send_blocking panics
586+
// when called from inside a tokio runtime.
587+
self.tx.send_blocking(Action::Shutdown { reply: None }).ok();
585588
let handle = handle.take().expect("this can only run once");
586589
if let Err(err) = handle.join() {
587590
warn!(?err, "Failed to join sync actor");
@@ -593,7 +596,7 @@ impl Drop for SyncHandle {
593596
struct Actor {
594597
store: Store,
595598
states: OpenReplicas,
596-
action_rx: flume::Receiver<Action>,
599+
action_rx: async_channel::Receiver<Action>,
597600
content_status_callback: Option<ContentStatusCallback>,
598601
tasks: JoinSet<()>,
599602
}
@@ -619,10 +622,10 @@ impl Actor {
619622
}
620623
continue;
621624
}
622-
action = self.action_rx.recv_async() => {
625+
action = self.action_rx.recv() => {
623626
match action {
624627
Ok(action) => action,
625-
Err(flume::RecvError::Disconnected) => {
628+
Err(async_channel::RecvError) => {
626629
debug!("action channel disconnected");
627630
break None;
628631
}
@@ -979,17 +982,14 @@ impl OpenReplicas {
979982
}
980983

981984
async fn iter_to_channel_async<T: Send + 'static>(
982-
channel: flume::Sender<Result<T>>,
985+
channel: async_channel::Sender<Result<T>>,
983986
iter: Result<impl Iterator<Item = Result<T>>>,
984987
) -> Result<(), SendReplyError> {
985988
match iter {
986-
Err(err) => channel
987-
.send_async(Err(err))
988-
.await
989-
.map_err(send_reply_error)?,
989+
Err(err) => channel.send(Err(err)).await.map_err(send_reply_error)?,
990990
Ok(iter) => {
991991
for item in iter {
992-
channel.send_async(item).await.map_err(send_reply_error)?;
992+
channel.send(item).await.map_err(send_reply_error)?;
993993
}
994994
}
995995
}
@@ -1032,10 +1032,10 @@ mod tests {
10321032
let id = namespace.id();
10331033
sync.import_namespace(namespace.into()).await?;
10341034
sync.open(id, Default::default()).await?;
1035-
let (tx, rx) = flume::bounded(10);
1035+
let (tx, rx) = async_channel::bounded(10);
10361036
sync.subscribe(id, tx).await?;
10371037
sync.close(id).await?;
1038-
assert!(rx.recv_async().await.is_err());
1038+
assert!(rx.recv().await.is_err());
10391039
Ok(())
10401040
}
10411041
}

iroh-docs/src/engine.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,15 @@ impl Engine {
170170

171171
// Subscribe to insert events from the replica.
172172
let a = {
173-
let (s, r) = flume::bounded(SUBSCRIBE_CHANNEL_CAP);
173+
let (s, r) = async_channel::bounded(SUBSCRIBE_CHANNEL_CAP);
174174
this.sync.subscribe(namespace, s).await?;
175-
r.into_stream()
176-
.map(move |ev| LiveEvent::from_replica_event(ev, &content_status_cb))
175+
Box::pin(r).map(move |ev| LiveEvent::from_replica_event(ev, &content_status_cb))
177176
};
178177

179178
// Subscribe to events from the [`live::Actor`].
180179
let b = {
181-
let (s, r) = flume::bounded(SUBSCRIBE_CHANNEL_CAP);
180+
let (s, r) = async_channel::bounded(SUBSCRIBE_CHANNEL_CAP);
181+
let r = Box::pin(r);
182182
let (reply, reply_rx) = oneshot::channel();
183183
this.to_live_actor
184184
.send(ToLiveActor::Subscribe {
@@ -188,7 +188,7 @@ impl Engine {
188188
})
189189
.await?;
190190
reply_rx.await??;
191-
r.into_stream().map(|event| Ok(LiveEvent::from(event)))
191+
r.map(|event| Ok(LiveEvent::from(event)))
192192
};
193193

194194
Ok(a.or(b))

iroh-docs/src/engine/live.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub enum ToLiveActor {
7878
Subscribe {
7979
namespace: NamespaceId,
8080
#[debug("sender")]
81-
sender: flume::Sender<Event>,
81+
sender: async_channel::Sender<Event>,
8282
#[debug("oneshot::Sender")]
8383
reply: sync::oneshot::Sender<Result<()>>,
8484
},
@@ -153,8 +153,8 @@ pub struct LiveActor<B: iroh_blobs::store::Store> {
153153
gossip: Gossip,
154154
bao_store: B,
155155
downloader: Downloader,
156-
replica_events_tx: flume::Sender<crate::Event>,
157-
replica_events_rx: flume::Receiver<crate::Event>,
156+
replica_events_tx: async_channel::Sender<crate::Event>,
157+
replica_events_rx: async_channel::Receiver<crate::Event>,
158158

159159
/// Send messages to self.
160160
/// Note: Must not be used in methods called from `Self::run` directly to prevent deadlocks.
@@ -192,7 +192,7 @@ impl<B: iroh_blobs::store::Store> LiveActor<B> {
192192
sync_actor_tx: mpsc::Sender<ToLiveActor>,
193193
gossip_actor_tx: mpsc::Sender<ToGossipActor>,
194194
) -> Self {
195-
let (replica_events_tx, replica_events_rx) = flume::bounded(1024);
195+
let (replica_events_tx, replica_events_rx) = async_channel::bounded(1024);
196196
Self {
197197
inbox,
198198
sync,
@@ -262,7 +262,7 @@ impl<B: iroh_blobs::store::Store> LiveActor<B> {
262262
}
263263
}
264264
}
265-
event = self.replica_events_rx.recv_async() => {
265+
event = self.replica_events_rx.recv() => {
266266
trace!(?i, "tick: replica_event");
267267
inc!(Metrics, doc_live_tick_replica_event);
268268
let event = event.context("replica_events closed")?;
@@ -865,7 +865,7 @@ impl From<&SyncFinished> for SyncDetails {
865865
struct SubscribersMap(HashMap<NamespaceId, Subscribers>);
866866

867867
impl SubscribersMap {
868-
fn subscribe(&mut self, namespace: NamespaceId, sender: flume::Sender<Event>) {
868+
fn subscribe(&mut self, namespace: NamespaceId, sender: async_channel::Sender<Event>) {
869869
self.0.entry(namespace).or_default().subscribe(sender);
870870
}
871871

@@ -930,15 +930,15 @@ impl QueuedHashes {
930930
}
931931

932932
#[derive(Debug, Default)]
933-
struct Subscribers(Vec<flume::Sender<Event>>);
933+
struct Subscribers(Vec<async_channel::Sender<Event>>);
934934

935935
impl Subscribers {
936-
fn subscribe(&mut self, sender: flume::Sender<Event>) {
936+
fn subscribe(&mut self, sender: async_channel::Sender<Event>) {
937937
self.0.push(sender)
938938
}
939939

940940
async fn send(&mut self, event: Event) -> bool {
941-
let futs = self.0.iter().map(|sender| sender.send_async(event.clone()));
941+
let futs = self.0.iter().map(|sender| sender.send(event.clone()));
942942
let res = futures_buffered::join_all(futs).await;
943943
// reverse the order so removing does not shift remaining indices
944944
for (i, res) in res.into_iter().enumerate().rev() {
@@ -977,8 +977,8 @@ mod tests {
977977
#[tokio::test]
978978
async fn test_sync_remove() {
979979
let pk = PublicKey::from_bytes(&[1; 32]).unwrap();
980-
let (a_tx, a_rx) = flume::unbounded();
981-
let (b_tx, b_rx) = flume::unbounded();
980+
let (a_tx, a_rx) = async_channel::unbounded();
981+
let (b_tx, b_rx) = async_channel::unbounded();
982982
let mut subscribers = Subscribers::default();
983983
subscribers.subscribe(a_tx);
984984
subscribers.subscribe(b_tx);

0 commit comments

Comments
 (0)