mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 21:36:29 +03:00
smtp: retry immediately if connection is stale
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
- allow removing quotes on existing drafts (#2950)
|
||||
- update provider database (11 Jan 2022) #2959
|
||||
- python: allow timeout for internal configure tracker API #2967
|
||||
- Replace `SendMsgToSmtp` jobs which stored outgoing messages in blobdir with `smtp` SQL table #2939 #2966
|
||||
|
||||
### Fixed
|
||||
- Fix: Make `add_parts()` not early-exit #2879
|
||||
|
||||
@@ -318,7 +318,7 @@ impl Job {
|
||||
return Status::RetryLater;
|
||||
}
|
||||
|
||||
let status = smtp_send(context, recipients, body, smtp, msg_id, 0).await;
|
||||
let status = smtp_send(context, &recipients, &body, smtp, msg_id, 0).await;
|
||||
if matches!(status, Status::Finished(Ok(_))) {
|
||||
// Remove additional SendMdn jobs we have aggregated into this one.
|
||||
job_try!(kill_ids(context, &additional_job_ids).await);
|
||||
|
||||
52
src/smtp.rs
52
src/smtp.rs
@@ -225,10 +225,16 @@ impl Smtp {
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to send a message.
|
||||
///
|
||||
/// Returns Status::Finished if sending the message should not be retried anymore,
|
||||
/// Status::RetryLater if sending should be postponed and Status::RetryNow if it is suspected that
|
||||
/// temporary failure is caused by stale connection, in which case a second attempt to send the
|
||||
/// same message may be done immediately.
|
||||
pub(crate) async fn smtp_send(
|
||||
context: &Context,
|
||||
recipients: Vec<async_smtp::EmailAddress>,
|
||||
message: String,
|
||||
recipients: &[async_smtp::EmailAddress],
|
||||
message: &str,
|
||||
smtp: &mut Smtp,
|
||||
msg_id: MsgId,
|
||||
rowid: i64,
|
||||
@@ -241,7 +247,7 @@ pub(crate) async fn smtp_send(
|
||||
smtp.connectivity.set_working(context).await;
|
||||
|
||||
let send_result = smtp
|
||||
.send(context, recipients, message.into_bytes(), rowid)
|
||||
.send(context, recipients, message.as_bytes(), rowid)
|
||||
.await;
|
||||
smtp.last_send_error = send_result.as_ref().err().map(|e| e.to_string());
|
||||
|
||||
@@ -362,7 +368,7 @@ pub(crate) async fn send_msg_to_smtp(
|
||||
.await
|
||||
.context("SMTP connection failure")
|
||||
{
|
||||
smtp.last_send_error = Some(format!("SMTP connection failure: {:#}", err));
|
||||
smtp.last_send_error = Some(format!("{:#}", err));
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
@@ -392,7 +398,43 @@ pub(crate) async fn send_msg_to_smtp(
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let status = smtp_send(context, recipients_list, body, smtp, msg_id, rowid).await;
|
||||
let status = match smtp_send(
|
||||
context,
|
||||
&recipients_list,
|
||||
body.as_str(),
|
||||
smtp,
|
||||
msg_id,
|
||||
rowid,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Status::RetryNow => {
|
||||
// Do a single retry immediately without increasing retry counter in case of stale
|
||||
// connection.
|
||||
info!(context, "Doing immediate retry to send message.");
|
||||
|
||||
// smtp_send just closed stale SMTP connection, reconnect and try again.
|
||||
if let Err(err) = smtp
|
||||
.connect_configured(context)
|
||||
.await
|
||||
.context("failed to reopen stale SMTP connection")
|
||||
{
|
||||
smtp.last_send_error = Some(format!("{:#}", err));
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
smtp_send(
|
||||
context,
|
||||
&recipients_list,
|
||||
body.as_str(),
|
||||
smtp,
|
||||
msg_id,
|
||||
rowid,
|
||||
)
|
||||
.await
|
||||
}
|
||||
status => status,
|
||||
};
|
||||
match status {
|
||||
Status::Finished(res) => {
|
||||
if res.is_ok() {
|
||||
|
||||
@@ -28,8 +28,8 @@ impl Smtp {
|
||||
pub async fn send(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
recipients: Vec<EmailAddress>,
|
||||
message: Vec<u8>,
|
||||
recipients: &[EmailAddress],
|
||||
message: &[u8],
|
||||
rowid: i64,
|
||||
) -> Result<()> {
|
||||
let message_len_bytes = message.len();
|
||||
@@ -53,7 +53,7 @@ impl Smtp {
|
||||
let mail = SendableEmail::new(
|
||||
envelope,
|
||||
rowid.to_string(), // only used for internal logging
|
||||
&message,
|
||||
message,
|
||||
);
|
||||
|
||||
if let Some(ref mut transport) = self.transport {
|
||||
|
||||
Reference in New Issue
Block a user