Tokio-util Framed and flushing

tokio-rustls is very clear about the need to explicitly flush. I put a tokio-rustls stream in a tokio-util Framed and didn't explicitly flush, and it seemed to work fine, to the point where I started assuming that Framed must be explicitly flushing each frame sent to it via its Encoder. However, recently I've been having some hiccups that look suspiciously like an effect of absent explicit flushes, so I thought I'd assume I was wrong and add them to see if the problem goes away.

Naively I thought I could just call frmio.flush().await, but it [the compiler] tells me I need some type annotations, and suggests this beauty:

<Framed<C, Codec> as futures::SinkExt<&MyType>>::flush(frmio).await;

(C is a generic with a AsyncWrite + Unpin + Send bound).

It feels a little strange to have to tell it what type (MyType) is being flushed. Just want to make sure -- what is the proper way to flush a Framed/FramedWrite?

I believe "normal" (or at least simple) use of a Sink like Framed & FramedWrite would just involve the use of SinkExt::send(), which takes care of flushing for you. Note the note in the docs about combining flushing & batching; if you have multiple items you want to send together, it may be more efficient to either (a) call feed() multiple times and then flush(), or (b) call send_all().

As for the syntax for calling flush(), as long as SinkExt is in scope and nothing else is providing a flush() method, you should just be able to write frmio.flush().await — unless the item type of the sink is generic (like AsRef<str> when using LinesCodec), in which case you'll have to write SinkExt::<SomeExplicitItemType>::flush(&mut frmio).await.

1 Like