I've had the honor to dive into the code. It's great, but I thing putting the whole message into the heap is potentially troublesome. Not so much on the detla.chat client side I suppose, but on a tiny server with at most 500 MB memory, and emails easily as big as 50 MB, this design would not fly. I've checked the Transport implementations briefly and it seems we could add streaming API to all of them without breaking the current big body API which could then be based on the streaming API.
async fn send(&mut self, email: SendableEmail) -> SmtpResult {
todo!("with default implementation using send_stream(...)")
}
async fn send_stream(&mut self, email: SendableEmailWithoutBody) -> Result<Box<dyn MailStream>, Error>;
pub trait MailStream : AsyncWrite {
/// this will take care of flushing, collecting the response and closing
async fn done(self) -> Resul<Response,Error>;
}
It might work out without a breaking change. To back the case, here's my WIP LMTP output for Samotop. Anyone can implement the MailQueue, it is part of the API. MailQueue.mail(Envelope) returns a sink for the mail data. This is then used by the server to write incoming mail body to. It is already implemented for the primitive SimpleDirMail and I'm dropping futures::Sink in favor of AsyncWrite. The traits are very similar, especially when it comes to bytes.
Ahoj!
I've had the honor to dive into the code. It's great, but I thing putting the whole message into the heap is potentially troublesome. Not so much on the detla.chat client side I suppose, but on a tiny server with at most 500 MB memory, and emails easily as big as 50 MB, this design would not fly. I've checked the Transport implementations briefly and it seems we could add streaming API to all of them without breaking the current big body API which could then be based on the streaming API.
Current signature:
Proposal (pseudo code):
It might work out without a breaking change. To back the case, here's my WIP LMTP output for Samotop. Anyone can implement the
MailQueue
, it is part of the API.MailQueue.mail(Envelope)
returns a sink for the mail data. This is then used by the server to write incoming mail body to. It is already implemented for the primitiveSimpleDirMail
and I'm droppingfutures::Sink
in favor ofAsyncWrite
. The traits are very similar, especially when it comes to bytes.