feat: Make resending OutPending messages possible (#5817)

This makes possible to schedule one more sending of the message, the existing jobs are not
cancelled. Otherwise it's complicated to implement bots that resend messages when a new member joins
the group.
This commit is contained in:
iequidoo
2024-09-14 18:48:13 -03:00
committed by iequidoo
parent afb01e3e90
commit b69488685f
2 changed files with 37 additions and 4 deletions

View File

@@ -4260,7 +4260,11 @@ pub async fn resend_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
msg.update_param(context).await?;
}
match msg.get_state() {
MessageState::OutFailed | MessageState::OutDelivered | MessageState::OutMdnRcvd => {
// `get_state()` may return an outdated `OutPending`, so update anyway.
MessageState::OutPending
| MessageState::OutFailed
| MessageState::OutDelivered
| MessageState::OutMdnRcvd => {
message::update_msg_state(context, msg.id, MessageState::OutPending).await?
}
msg_state => bail!("Unexpected message state {msg_state}"),
@@ -6846,8 +6850,29 @@ mod tests {
)
.await?;
let sent2 = alice.pop_sent_msg().await;
resend_msgs(&alice, &[sent1.sender_msg_id]).await?;
let resent_msg_id = sent1.sender_msg_id;
resend_msgs(&alice, &[resent_msg_id]).await?;
assert_eq!(
resent_msg_id.get_state(&alice).await?,
MessageState::OutPending
);
resend_msgs(&alice, &[resent_msg_id]).await?;
// Message can be re-sent multiple times.
assert_eq!(
resent_msg_id.get_state(&alice).await?,
MessageState::OutPending
);
alice.pop_sent_msg().await;
// There's still one more pending SMTP job.
assert_eq!(
resent_msg_id.get_state(&alice).await?,
MessageState::OutPending
);
let sent3 = alice.pop_sent_msg().await;
assert_eq!(
resent_msg_id.get_state(&alice).await?,
MessageState::OutDelivered
);
// Bob receives all messages
let bob = TestContext::new_bob().await;

View File

@@ -474,9 +474,17 @@ impl TestContext {
.execute("DELETE FROM smtp WHERE id=?;", (rowid,))
.await
.expect("failed to remove job");
update_msg_state(&self.ctx, msg_id, MessageState::OutDelivered)
if !self
.ctx
.sql
.exists("SELECT COUNT(*) FROM smtp WHERE msg_id=?", (msg_id,))
.await
.expect("failed to update message state");
.expect("Failed to check for more jobs")
{
update_msg_state(&self.ctx, msg_id, MessageState::OutDelivered)
.await
.expect("failed to update message state");
}
let payload_headers = payload.split("\r\n\r\n").next().unwrap().lines();
let payload_header_names: Vec<_> = payload_headers