Idiomatic sharing across async channels

In terms of design, I have a set of reference data (e.g. list of towns) and when that changes I want to send it out across a watch channel to the many receivers of that channel.

For efficiency I obviously don't want to clone the reference data, but in order to pass a reference I would need to tell the borrow checker that every receiver's lifetime is less than the owner of the towns, and I just can't get my head around how to do that.

Would it be more idiomatic to wrap it in an Arc/Lock and send that instead?

I'm not so much looking for code, just idiomatic design pointers please (although code is gratefully received, obviously!)

EDIT: to be explicit, the receivers will want to hold onto the reference beyond the scope of the receive

Well in that case:

  • If your town "objects" are light-weight, then you can simply clone them
  • Otherwise, you're better off with Arc
1 Like

In general, a channel will need to own the data it is receiving otherwise you'll run into lifetime issues. That means if you want to pass the entire data structure around you'll need to either clone it or put it behind some sort of shared pointer.

My suggestion would be to only send diffs (e.g. "this new town was added") across the channel or have a look at the immutable data structures in the im crate (which effectively uses Arc internally).

Alternatively, you could switch from channels which own data to a callback/event listener model where you call some sort of listener.on_changed(&self.towns) method. Then if the listener wants to clone the value or do expensive stuff, it can.

1 Like

Other options that may be obvious but I'll mention them anyway:

  • Use Arc<Towns> and only clone the data once (not a copy per receiver) when it changes.
  • Use Arc<RwLock<Towns>>. The drawback is that readers are blocked while modifications are being made.

The best choice probably depends on how often the towns are accessed by readers, how often towns are changed, the size of the towns data structure, and whether performance here matters very much in the bigger picture of your app.

1 Like

Thanks @RedDocMD, @Michael-F-Bryan, and @jumpnbrownweasel. All of your replies were exactly what I was looking for.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.