feat: Use IMAP APPEND command to upload sync messages (#5845)

Why:
- With IMAP APPEND we can upload messages directly to the DeltaChat folder (for non-chatmail
  accounts).
- We can set the `\Seen` flag immediately so that if the user has other MUA, it doesn't alert about
  a new message if it's just a sync message (there were several such reports on the support
  forum). Though this also isn't useful for chatmail.
- We don't need SMTP envelope and overall remove some overhead on processing sync messages.
This commit is contained in:
iequidoo
2024-08-16 12:29:21 -03:00
committed by iequidoo
parent 0b908db272
commit d6845bd5e9
13 changed files with 184 additions and 68 deletions

View File

@@ -2245,7 +2245,7 @@ pub(crate) async fn sync(context: &Context, id: SyncId, action: SyncAction) -> R
context
.add_sync_item(SyncData::AlterChat { id, action })
.await?;
context.scheduler.interrupt_smtp().await;
context.scheduler.interrupt_inbox().await;
Ok(())
}
@@ -2906,10 +2906,9 @@ async fn prepare_send_msg(
create_send_msg_jobs(context, msg).await
}
/// Constructs jobs for sending a message and inserts them into the `smtp` table.
/// Constructs jobs for sending a message and inserts them into the appropriate table.
///
/// Returns row ids if jobs were created or an empty `Vec` otherwise, e.g. when sending to a
/// group with only self and no BCC-to-self configured.
/// Returns row ids if `smtp` table jobs were created or an empty `Vec` otherwise.
///
/// The caller has to interrupt SMTP loop or otherwise process new rows.
pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -> Result<Vec<i64>> {
@@ -3003,12 +3002,6 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
}
}
if let Some(sync_ids) = rendered_msg.sync_ids_to_delete {
if let Err(err) = context.delete_sync_ids(sync_ids).await {
error!(context, "Failed to delete sync ids: {err:#}.");
}
}
if attach_selfavatar {
if let Err(err) = msg.chat_id.set_selfavatar_timestamp(context, now).await {
error!(context, "Failed to set selfavatar timestamp: {err:#}.");
@@ -3025,19 +3018,30 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
let chunk_size = context.get_max_smtp_rcpt_to().await?;
let trans_fn = |t: &mut rusqlite::Transaction| {
let mut row_ids = Vec::<i64>::new();
for recipients_chunk in recipients.chunks(chunk_size) {
let recipients_chunk = recipients_chunk.join(" ");
let row_id = t.execute(
"INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id) \
VALUES (?1, ?2, ?3, ?4)",
(
&rendered_msg.rfc724_mid,
recipients_chunk,
&rendered_msg.message,
msg.id,
),
if let Some(sync_ids) = rendered_msg.sync_ids_to_delete {
t.execute(
&format!("DELETE FROM multi_device_sync WHERE id IN ({sync_ids})"),
(),
)?;
row_ids.push(row_id.try_into()?);
t.execute(
"INSERT INTO imap_send (mime, msg_id) VALUES (?, ?)",
(&rendered_msg.message, msg.id),
)?;
} else {
for recipients_chunk in recipients.chunks(chunk_size) {
let recipients_chunk = recipients_chunk.join(" ");
let row_id = t.execute(
"INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id) \
VALUES (?1, ?2, ?3, ?4)",
(
&rendered_msg.rfc724_mid,
recipients_chunk,
&rendered_msg.message,
msg.id,
),
)?;
row_ids.push(row_id.try_into()?);
}
}
Ok(row_ids)
};
@@ -3793,7 +3797,7 @@ pub(crate) async fn add_contact_to_chat_ex(
.log_err(context)
.is_ok()
{
context.scheduler.interrupt_smtp().await;
context.scheduler.interrupt_inbox().await;
}
}
context.emit_event(EventType::ChatModified(chat_id));