Flume fix part 2: avoid using flume in a couple of cases, and revert attempted fix#1 (#396)

* A second attempt to avoid the flume memory leak, since the first didn't actually work

* No luck with second flume fix, so revert to futures::mpsc in a few places)

* cargo fmt

* Add a comment to cover use of into_stream
This commit is contained in:
James Wilson
2021-09-03 15:55:25 +01:00
committed by GitHub
parent 2932075783
commit a3ffaf3c44
7 changed files with 29 additions and 43 deletions
+8 -7
View File
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use super::on_close::OnClose;
use futures::{channel, StreamExt};
use soketto::handshake::{Client, ServerResponse};
use std::sync::Arc;
use tokio::net::TcpStream;
@@ -71,7 +72,7 @@ impl Connection {
let mut rx_closed2 = tx_closed1.subscribe();
// Receive messages from the socket:
let (tx_to_external, rx_from_ws) = flume::unbounded();
let (tx_to_external, rx_from_ws) = channel::mpsc::unbounded();
tokio::spawn(async move {
let mut send_to_external = true;
loop {
@@ -110,7 +111,7 @@ impl Connection {
.map_err(|e| e.into()),
};
if let Err(e) = tx_to_external.send_async(msg).await {
if let Err(e) = tx_to_external.unbounded_send(msg) {
// Our external channel may have closed or errored, but the socket hasn't
// been closed, so keep receiving in order to allow the socket to continue to
// function properly (we may be happy just sending messages to it), but stop
@@ -122,12 +123,12 @@ impl Connection {
});
// Send messages to the socket:
let (tx_to_ws, rx_from_external) = flume::unbounded::<SentMessage>();
let (tx_to_ws, mut rx_from_external) = channel::mpsc::unbounded::<SentMessage>();
tokio::spawn(async move {
loop {
// Wait for messages, or bail entirely if asked to close.
let msg = tokio::select! {
msg = rx_from_external.recv_async() => { msg },
msg = rx_from_external.next() => { msg },
_ = rx_closed2.recv() => {
// attempt to gracefully end the connection.
let _ = ws_to_connection.close().await;
@@ -139,8 +140,8 @@ impl Connection {
// needs to keep receiving data for the WS connection to stay open, there's no
// reason to keep this side of the loop open if our channel is closed.
let msg = match msg {
Ok(msg) => msg,
_ => break,
Some(msg) => msg,
None => break,
};
// We don't explicitly shut down the channel if we hit send errors. Why? Because the
@@ -205,7 +206,7 @@ impl Connection {
closer: Arc::clone(&on_close),
},
Receiver {
inner: crate::flume_receiver_into_stream(rx_from_ws),
inner: rx_from_ws,
closer: on_close,
},
)
+2 -2
View File
@@ -15,12 +15,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use super::on_close::OnClose;
use futures::{Stream, StreamExt};
use futures::{channel, Stream, StreamExt};
use std::sync::Arc;
/// Receive messages out of a connection
pub struct Receiver {
pub(super) inner: crate::FlumeRecvStream<'static, Result<RecvMessage, RecvError>>,
pub(super) inner: channel::mpsc::UnboundedReceiver<Result<RecvMessage, RecvError>>,
pub(super) closer: Arc<OnClose>,
}
+8 -5
View File
@@ -15,6 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use super::on_close::OnClose;
use futures::channel;
use std::sync::Arc;
/// A message that can be sent into the channel interface
@@ -39,7 +40,7 @@ pub enum SentMessage {
/// Send messages into the connection
#[derive(Clone)]
pub struct Sender {
pub(super) inner: flume::Sender<SentMessage>,
pub(super) inner: channel::mpsc::UnboundedSender<SentMessage>,
pub(super) closer: Arc<OnClose>,
}
@@ -51,19 +52,21 @@ impl Sender {
}
/// Returns whether this channel is closed.
pub fn is_closed(&self) -> bool {
self.inner.is_disconnected()
self.inner.is_closed()
}
/// Unbounded send will always queue the message and doesn't
/// need to be awaited.
pub fn unbounded_send(&self, msg: SentMessage) -> Result<(), flume::SendError<SentMessage>> {
self.inner.send(msg)?;
pub fn unbounded_send(&self, msg: SentMessage) -> Result<(), channel::mpsc::SendError> {
self.inner
.unbounded_send(msg)
.map_err(|e| e.into_send_error())?;
Ok(())
}
/// Convert this sender into a Sink
pub fn into_sink(
self,
) -> impl futures::Sink<SentMessage> + std::marker::Unpin + Clone + 'static {
self.inner.into_sink()
self.inner
}
}