Skip to content

Commit

Permalink
Implement detached signal sender
Browse files Browse the repository at this point in the history
Allow signals to be sent detached from the channel struct.

This is done using a higher-order function and by cloning the sender so
it can be used independently of the `Channel`.

This is useful to be able to spawn a cancelation handler separately from
the main `Channel` recieve loop.

Signed-off-by: Joe Grund <[email protected]>
f08f74

Signed-off-by: Joe Grund <[email protected]>
  • Loading branch information
jgrund committed Jun 8, 2024
1 parent 800969b commit 2b289c2
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion russh/src/channels/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::Arc;
use std::{pin::Pin, sync::Arc};

use futures::{Future, FutureExt as _};
use russh_cryptovec::CryptoVec;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::sync::mpsc::{Sender, UnboundedReceiver};
Expand Down Expand Up @@ -318,6 +319,26 @@ impl<S: From<(ChannelId, ChannelMsg)> + Send + Sync + 'static> Channel<S> {
pub async fn close(&self) -> Result<(), Error> {
self.send_msg(ChannelMsg::Close).await
}
/// Get a `FnOnce` that can be used to send a signal through this channel
pub fn get_signal_sender(
&self,
) -> impl FnOnce(Sig) -> Pin<Box<dyn Future<Output = Result<(), Error>> + std::marker::Send>>
{
let sender = self.sender.clone();
let id = self.id;

move |signal| {
async move {
sender
.send((id, ChannelMsg::Signal { signal }).into())
.await
.map_err(|_| Error::SendError)?;

Ok(())
}
.boxed()
}
}

async fn send_msg(&self, msg: ChannelMsg) -> Result<(), Error> {
self.sender
Expand Down

0 comments on commit 2b289c2

Please sign in to comment.