Skip to content

Commit 6e3c2fc

Browse files
committed
dc_receive_imf: simplify timestamp calculation
Reduce the number of mutable variables and out parameters in `add_parts`. Also don't call `dc_create_smeared_timestamp` if there is no `Date` header. Timestamps are only supposed to be "created" when the message is sent, not received, to make sure sent messages are sorted properly in MUAs that only use the date for sorting. Delta Chat uses database IDs for sorting in addition to timestamps, so it can sort messages with equal timestamps properly. Update `dc_smeared_time` documentation. Turn `dc_smeared_time` and `dc_create_smeared_timestamp` comments into documentation comments.
1 parent 30e616f commit 6e3c2fc

File tree

2 files changed

+22
-32
lines changed

2 files changed

+22
-32
lines changed

src/dc_receive_imf.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Internet Message Format reception pipeline.
22
3+
use std::cmp::min;
34
use std::convert::TryFrom;
45

56
use anyhow::{bail, ensure, Result};
@@ -18,9 +19,7 @@ use crate::constants::{
1819
};
1920
use crate::contact::{addr_cmp, normalize_name, Contact, Origin, VerifiedStatus};
2021
use crate::context::Context;
21-
use crate::dc_tools::{
22-
dc_create_smeared_timestamp, dc_extract_grpid_from_rfc724_mid, dc_smeared_time,
23-
};
22+
use crate::dc_tools::{dc_extract_grpid_from_rfc724_mid, dc_smeared_time};
2423
use crate::download::DownloadState;
2524
use crate::ephemeral::{stock_ephemeral_timer_changed, Timer as EphemeralTimer};
2625
use crate::events::EventType;
@@ -106,15 +105,6 @@ pub(crate) async fn dc_receive_imf_inner(
106105
return Ok(());
107106
}
108107

109-
let mut sent_timestamp = if let Some(value) = mime_parser
110-
.get_header(HeaderDef::Date)
111-
.and_then(|value| mailparse::dateparse(value).ok())
112-
{
113-
value
114-
} else {
115-
dc_create_smeared_timestamp(context).await
116-
};
117-
118108
let rfc724_mid = mime_parser.get_rfc724_mid().unwrap_or_else(||
119109
// missing Message-IDs may come if the mail was set from this account with another
120110
// client that relies in the SMTP server to generate one.
@@ -193,6 +183,12 @@ pub(crate) async fn dc_receive_imf_inner(
193183
.await?,
194184
);
195185

186+
let rcvd_timestamp = dc_smeared_time(context).await;
187+
let sent_timestamp = mime_parser
188+
.get_header(HeaderDef::Date)
189+
.and_then(|value| mailparse::dateparse(value).ok())
190+
.map_or(rcvd_timestamp, |value| min(value, rcvd_timestamp));
191+
196192
// Add parts
197193
let chat_id = add_parts(
198194
context,
@@ -204,7 +200,8 @@ pub(crate) async fn dc_receive_imf_inner(
204200
server_uid,
205201
&to_ids,
206202
rfc724_mid,
207-
&mut sent_timestamp,
203+
sent_timestamp,
204+
rcvd_timestamp,
208205
from_id,
209206
&mut hidden,
210207
seen || replace_partial_download,
@@ -406,7 +403,8 @@ async fn add_parts(
406403
server_uid: u32,
407404
to_ids: &ContactIds,
408405
rfc724_mid: String,
409-
sent_timestamp: &mut i64,
406+
sent_timestamp: i64,
407+
rcvd_timestamp: i64,
410408
from_id: u32,
411409
hidden: &mut bool,
412410
seen: bool,
@@ -455,9 +453,6 @@ async fn add_parts(
455453
}
456454
}
457455

458-
let rcvd_timestamp = dc_smeared_time(context).await;
459-
*sent_timestamp = std::cmp::min(*sent_timestamp, rcvd_timestamp);
460-
461456
// check if the message introduces a new chat:
462457
// - outgoing messages introduce a chat with the first to: address if they are sent by a messenger
463458
// - incoming messages introduce a chat only for known contacts if they are sent by a messenger
@@ -531,7 +526,7 @@ async fn add_parts(
531526
if let Some((new_chat_id, new_chat_id_blocked)) = create_or_lookup_group(
532527
context,
533528
&mut mime_parser,
534-
*sent_timestamp,
529+
sent_timestamp,
535530
if test_normal_chat.is_none() {
536531
allow_creation
537532
} else {
@@ -761,7 +756,7 @@ async fn add_parts(
761756
if let Some((new_chat_id, new_chat_id_blocked)) = create_or_lookup_group(
762757
context,
763758
&mut mime_parser,
764-
*sent_timestamp,
759+
sent_timestamp,
765760
allow_creation,
766761
Blocked::Not,
767762
from_id,
@@ -857,7 +852,7 @@ async fn add_parts(
857852
// correct message_timestamp, it should not be used before,
858853
// however, we cannot do this earlier as we need chat_id to be set
859854
let in_fresh = state == MessageState::InFresh;
860-
let sort_timestamp = calc_sort_timestamp(context, *sent_timestamp, chat_id, in_fresh).await?;
855+
let sort_timestamp = calc_sort_timestamp(context, sent_timestamp, chat_id, in_fresh).await?;
861856

862857
// Apply ephemeral timer changes to the chat.
863858
//
@@ -896,7 +891,7 @@ async fn add_parts(
896891
chat_id
897892
);
898893
} else if chat_id
899-
.update_timestamp(context, Param::EphemeralSettingsTimestamp, *sent_timestamp)
894+
.update_timestamp(context, Param::EphemeralSettingsTimestamp, sent_timestamp)
900895
.await?
901896
{
902897
if let Err(err) = chat_id
@@ -967,7 +962,7 @@ async fn add_parts(
967962
.update_timestamp(
968963
context,
969964
Param::ProtectionSettingsTimestamp,
970-
*sent_timestamp,
965+
sent_timestamp,
971966
)
972967
.await?
973968
{
@@ -1047,7 +1042,6 @@ async fn add_parts(
10471042
Vec::new()
10481043
};
10491044

1050-
let sent_timestamp = *sent_timestamp;
10511045
let is_hidden = *hidden;
10521046

10531047
let mut is_hidden = is_hidden;
@@ -1304,11 +1298,7 @@ async fn calc_sort_timestamp(
13041298
}
13051299
}
13061300

1307-
if sort_timestamp >= dc_smeared_time(context).await {
1308-
sort_timestamp = dc_create_smeared_timestamp(context).await;
1309-
}
1310-
1311-
Ok(sort_timestamp)
1301+
Ok(min(sort_timestamp, dc_smeared_time(context).await))
13121302
}
13131303

13141304
async fn lookup_chat_by_reply(

src/dc_tools.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ pub(crate) fn dc_gm2local_offset() -> i64 {
8484
// but at max `MAX_SECONDS_TO_LEND_FROM_FUTURE`
8585
const MAX_SECONDS_TO_LEND_FROM_FUTURE: i64 = 5;
8686

87-
// returns the currently smeared timestamp,
88-
// may be used to check if call to dc_create_smeared_timestamp() is needed or not.
89-
// the returned timestamp MUST NOT be used to be sent out or saved in the database!
87+
/// Returns the current smeared timestamp,
88+
///
89+
/// The returned timestamp MUST NOT be sent out.
9090
pub(crate) async fn dc_smeared_time(context: &Context) -> i64 {
9191
let mut now = time();
9292
let ts = *context.last_smeared_timestamp.read().await;
@@ -97,7 +97,7 @@ pub(crate) async fn dc_smeared_time(context: &Context) -> i64 {
9797
now
9898
}
9999

100-
// returns a timestamp that is guaranteed to be unique.
100+
/// Returns a timestamp that is guaranteed to be unique.
101101
pub(crate) async fn dc_create_smeared_timestamp(context: &Context) -> i64 {
102102
let now = time();
103103
let mut ret = now;

0 commit comments

Comments
 (0)