Repository: smol-rs/async-channel (Rust)

Issue:
Expose `sender_count` and `receiver_count`
I'm looking to migrate a piece of code from a custom channel implementation to async-channel, but one important need is the ability to have statistics about the channels (including sender and receiver count). I see the `Channel` struct [has that data](https://github.com/stjepang/async-channel/blob/d23f31f1e2fdde7b4388c6fb37ca3a090a4d04dc/src/lib.rs#L59), but it doesn't appear to be exposed on either `Sender` or `Receiver`.

Would you be amenable to a PR which adds:

```rust
pub fn sender_count(&self) -> usize;
pub fn receiver_count(&self) -> usize;
```

to both `Sender` and `Receiver`?


Discussion:
I would, that sounds reasonable! It'd be very similar to `Arc::strong_count()` and `Arc::weak_count()`.



Patch:
diff --git a/src/lib.rs b/src/lib.rs
index 66ce59a..ee364e3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -383,6 +383,44 @@ impl<T> Sender<T> {
     pub fn capacity(&self) -> Option<usize> {
         self.channel.queue.capacity()
     }
+
+    /// Returns the number of receivers for the channel.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # futures_lite::future::block_on(async {
+    /// use async_channel::unbounded;
+    ///
+    /// let (s, r) = unbounded::<()>();
+    /// assert_eq!(s.receiver_count(), 1);
+    ///
+    /// let r2 = r.clone();
+    /// assert_eq!(s.receiver_count(), 2);
+    /// # });
+    /// ```
+    pub fn receiver_count(&self) -> usize {
+        self.channel.receiver_count.load(Ordering::SeqCst)
+    }
+
+    /// Returns the number of receivers for the channel.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # futures_lite::future::block_on(async {
+    /// use async_channel::unbounded;
+    ///
+    /// let (s, r) = unbounded::<()>();
+    /// assert_eq!(s.sender_count(), 1);
+    ///
+    /// let s2 = s.clone();
+    /// assert_eq!(s.sender_count(), 2);
+    /// # });
+    /// ```
+    pub fn sender_count(&self) -> usize {
+        self.channel.sender_count.load(Ordering::SeqCst)
+    }
 }
 
 impl<T> Drop for Sender<T> {
@@ -641,6 +679,44 @@ impl<T> Receiver<T> {
     pub fn capacity(&self) -> Option<usize> {
         self.channel.queue.capacity()
     }
+
+    /// Returns the number of receivers for the channel.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # futures_lite::future::block_on(async {
+    /// use async_channel::unbounded;
+    ///
+    /// let (s, r) = unbounded::<()>();
+    /// assert_eq!(r.receiver_count(), 1);
+    ///
+    /// let r2 = r.clone();
+    /// assert_eq!(r.receiver_count(), 2);
+    /// # });
+    /// ```
+    pub fn receiver_count(&self) -> usize {
+        self.channel.receiver_count.load(Ordering::SeqCst)
+    }
+
+    /// Returns the number of receivers for the channel.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # futures_lite::future::block_on(async {
+    /// use async_channel::unbounded;
+    ///
+    /// let (s, r) = unbounded::<()>();
+    /// assert_eq!(r.sender_count(), 1);
+    ///
+    /// let s2 = s.clone();
+    /// assert_eq!(r.sender_count(), 2);
+    /// # });
+    /// ```
+    pub fn sender_count(&self) -> usize {
+        self.channel.sender_count.load(Ordering::SeqCst)
+    }
 }
 
 impl<T> Drop for Receiver<T> {


Test patch:
diff --git a/tests/bounded.rs b/tests/bounded.rs
index 1e18fc5..1220c0e 100644
--- a/tests/bounded.rs
+++ b/tests/bounded.rs
@@ -246,6 +246,34 @@ fn len() {
     assert_eq!(r.len(), 0);
 }
 
+#[test]
+fn receiver_count() {
+    let (s, r) = bounded::<()>(5);
+    let receiver_clones: Vec<_> = (0..20).map(|_| r.clone()).collect();
+
+    assert_eq!(s.receiver_count(), 21);
+    assert_eq!(r.receiver_count(), 21);
+
+    drop(receiver_clones);
+
+    assert_eq!(s.receiver_count(), 1);
+    assert_eq!(r.receiver_count(), 1);
+}
+
+#[test]
+fn sender_count() {
+    let (s, r) = bounded::<()>(5);
+    let sender_clones: Vec<_> = (0..20).map(|_| s.clone()).collect();
+
+    assert_eq!(s.sender_count(), 21);
+    assert_eq!(r.sender_count(), 21);
+
+    drop(sender_clones);
+
+    assert_eq!(s.receiver_count(), 1);
+    assert_eq!(r.receiver_count(), 1);
+}
+
 #[test]
 fn close_wakes_sender() {
     let (s, r) = bounded(1);
diff --git a/tests/unbounded.rs b/tests/unbounded.rs
index 84c38d8..c757270 100644
--- a/tests/unbounded.rs
+++ b/tests/unbounded.rs
@@ -173,6 +173,34 @@ fn len() {
     assert_eq!(r.len(), 0);
 }
 
+#[test]
+fn receiver_count() {
+    let (s, r) = unbounded::<()>();
+    let receiver_clones: Vec<_> = (0..20).map(|_| r.clone()).collect();
+
+    assert_eq!(s.receiver_count(), 21);
+    assert_eq!(r.receiver_count(), 21);
+
+    drop(receiver_clones);
+
+    assert_eq!(s.receiver_count(), 1);
+    assert_eq!(r.receiver_count(), 1);
+}
+
+#[test]
+fn sender_count() {
+    let (s, r) = unbounded::<()>();
+    let sender_clones: Vec<_> = (0..20).map(|_| s.clone()).collect();
+
+    assert_eq!(s.sender_count(), 21);
+    assert_eq!(r.sender_count(), 21);
+
+    drop(sender_clones);
+
+    assert_eq!(s.receiver_count(), 1);
+    assert_eq!(r.receiver_count(), 1);
+}
+
 #[test]
 fn close_wakes_receiver() {
     let (s, r) = unbounded::<()>();