Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use SystemTime instead of Instant everywhere #5108

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2806,12 +2806,14 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
);
}

let now = time();

if rendered_msg.is_gossiped {
msg.chat_id.set_gossiped_timestamp(context, time()).await?;
msg.chat_id.set_gossiped_timestamp(context, now).await?;
}

if let Some(last_added_location_id) = rendered_msg.last_added_location_id {
if let Err(err) = location::set_kml_sent_timestamp(context, msg.chat_id, time()).await {
if let Err(err) = location::set_kml_sent_timestamp(context, msg.chat_id, now).await {
error!(context, "Failed to set kml sent_timestamp: {err:#}.");
}
if !msg.hidden {
Expand All @@ -2830,7 +2832,7 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
}

if attach_selfavatar {
if let Err(err) = msg.chat_id.set_selfavatar_timestamp(context, time()).await {
if let Err(err) = msg.chat_id.set_selfavatar_timestamp(context, now).await {
error!(context, "Failed to set selfavatar timestamp: {err:#}.");
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 4;
pub(crate) const DEFAULT_MAX_SMTP_RCPT_TO: usize = 50;

/// How far the last quota check needs to be in the past to be checked by the background function (in seconds).
pub(crate) const DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT: i64 = 12 * 60 * 60; // 12 hours
pub(crate) const DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT: u64 = 12 * 60 * 60; // 12 hours

#[cfg(test)]
mod tests {
Expand Down
10 changes: 7 additions & 3 deletions src/contact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,12 @@ impl RecentlySeenLoop {
async fn run(context: Context, interrupt: Receiver<RecentlySeenInterrupt>) {
type MyHeapElem = (Reverse<i64>, ContactId);

let now = SystemTime::now();
let now_ts = now
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs() as i64;

// Priority contains all recently seen sorted by the timestamp
// when they become not recently seen.
//
Expand All @@ -1742,7 +1748,7 @@ impl RecentlySeenLoop {
.query_map(
"SELECT id, last_seen FROM contacts
WHERE last_seen > ?",
(time() - SEEN_RECENTLY_SECONDS,),
(now_ts - SEEN_RECENTLY_SECONDS,),
|row| {
let contact_id: ContactId = row.get("id")?;
let last_seen: i64 = row.get("last_seen")?;
Expand All @@ -1757,8 +1763,6 @@ impl RecentlySeenLoop {
.unwrap_or_default();

loop {
let now = SystemTime::now();

let (until, contact_id) =
if let Some((Reverse(timestamp), contact_id)) = unseen_queue.peek() {
(
Expand Down
31 changes: 17 additions & 14 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::{Duration, Instant, SystemTime};
use std::time::Duration;

use anyhow::{bail, ensure, Context as _, Result};
use async_channel::{self as channel, Receiver, Sender};
Expand All @@ -33,7 +33,7 @@ use crate::scheduler::{convert_folder_meaning, SchedulerState};
use crate::sql::Sql;
use crate::stock_str::StockStrings;
use crate::timesmearing::SmearedTimestamp;
use crate::tools::{create_id, duration_to_str, time};
use crate::tools::{self, create_id, duration_to_str, time, time_elapsed};

/// Builder for the [`Context`].
///
Expand Down Expand Up @@ -233,15 +233,15 @@ pub struct InnerContext {
/// IMAP METADATA.
pub(crate) metadata: RwLock<Option<ServerMetadata>>,

pub(crate) last_full_folder_scan: Mutex<Option<Instant>>,
pub(crate) last_full_folder_scan: Mutex<Option<tools::Time>>,

/// ID for this `Context` in the current process.
///
/// This allows for multiple `Context`s open in a single process where each context can
/// be identified by this ID.
pub(crate) id: u32,

creation_time: SystemTime,
creation_time: tools::Time,

/// The text of the last error logged and emitted as an event.
/// If the ui wants to display an error after a failure,
Expand All @@ -262,7 +262,7 @@ enum RunningState {
Running { cancel_sender: Sender<()> },

/// Cancel signal has been sent, waiting for ongoing process to be freed.
ShallStop { request: Instant },
ShallStop { request: tools::Time },

/// There is no ongoing process, a new one can be allocated.
Stopped,
Expand Down Expand Up @@ -394,7 +394,7 @@ impl Context {
new_msgs_notify,
server_id: RwLock::new(None),
metadata: RwLock::new(None),
creation_time: std::time::SystemTime::now(),
creation_time: tools::Time::now(),
last_full_folder_scan: Mutex::new(None),
last_error: std::sync::RwLock::new("".to_string()),
debug_logging: std::sync::RwLock::new(None),
Expand Down Expand Up @@ -454,7 +454,7 @@ impl Context {
}

let address = self.get_primary_self_addr().await?;
let time_start = std::time::SystemTime::now();
let time_start = tools::Time::now();
info!(self, "background_fetch started fetching {address}");

let _pause_guard = self.scheduler.pause(self.clone()).await?;
Expand All @@ -476,7 +476,10 @@ impl Context {
let quota = self.quota.read().await;
quota
.as_ref()
.filter(|quota| quota.modified + DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT > time())
.filter(|quota| {
time_elapsed(&quota.modified)
> Duration::from_secs(DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT)
})
.is_none()
};

Expand All @@ -489,7 +492,7 @@ impl Context {
info!(
self,
"background_fetch done for {address} took {:?}",
time_start.elapsed().unwrap_or_default()
time_elapsed(&time_start),
);

Ok(())
Expand Down Expand Up @@ -591,7 +594,7 @@ impl Context {
pub(crate) async fn free_ongoing(&self) {
let mut s = self.running_state.write().await;
if let RunningState::ShallStop { request } = *s {
info!(self, "Ongoing stopped in {:?}", request.elapsed());
info!(self, "Ongoing stopped in {:?}", time_elapsed(&request));
}
*s = RunningState::Stopped;
}
Expand All @@ -606,7 +609,7 @@ impl Context {
}
info!(self, "Signaling the ongoing process to stop ASAP.",);
*s = RunningState::ShallStop {
request: Instant::now(),
request: tools::Time::now(),
};
}
RunningState::ShallStop { .. } | RunningState::Stopped => {
Expand Down Expand Up @@ -867,8 +870,8 @@ impl Context {
.to_string(),
);

let elapsed = self.creation_time.elapsed();
res.insert("uptime", duration_to_str(elapsed.unwrap_or_default()));
let elapsed = time_elapsed(&self.creation_time);
res.insert("uptime", duration_to_str(elapsed));

Ok(res)
}
Expand Down Expand Up @@ -1214,7 +1217,7 @@ pub fn get_version_str() -> &'static str {

#[cfg(test)]
mod tests {
use std::time::Duration;
use std::time::{Duration, SystemTime};

use anyhow::Context as _;
use strum::IntoEnumIterator;
Expand Down
11 changes: 4 additions & 7 deletions src/imap/idle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::{Duration, SystemTime};
use std::time::Duration;

use anyhow::{bail, Context as _, Result};
use async_channel::Receiver;
Expand All @@ -11,6 +11,7 @@ use crate::config::Config;
use crate::context::Context;
use crate::imap::{client::IMAP_TIMEOUT, FolderMeaning};
use crate::log::LogExt;
use crate::tools::{self, time_elapsed};

/// Timeout after which IDLE is finished
/// if there are no responses from the server.
Expand Down Expand Up @@ -106,7 +107,7 @@ impl Imap {
// Idle using polling. This is also needed if we're not yet configured -
// in this case, we're waiting for a configure job (and an interrupt).

let fake_idle_start_time = SystemTime::now();
let fake_idle_start_time = tools::Time::now();

// Do not poll, just wait for an interrupt when no folder is passed in.
let watch_folder = if let Some(watch_folder) = watch_folder {
Expand Down Expand Up @@ -196,11 +197,7 @@ impl Imap {
info!(
context,
"IMAP-fake-IDLE done after {:.4}s",
SystemTime::now()
.duration_since(fake_idle_start_time)
.unwrap_or_default()
.as_millis() as f64
/ 1000.,
time_elapsed(&fake_idle_start_time).as_millis() as f64 / 1000.,
);
}
}
7 changes: 4 additions & 3 deletions src/imap/scan_folders.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::BTreeMap, time::Instant};
use std::collections::BTreeMap;

use anyhow::{Context as _, Result};
use futures::TryStreamExt;
Expand All @@ -7,6 +7,7 @@ use super::{get_folder_meaning_by_attrs, get_folder_meaning_by_name};
use crate::config::Config;
use crate::imap::Imap;
use crate::log::LogExt;
use crate::tools::{self, time_elapsed};
use crate::{context::Context, imap::FolderMeaning};

impl Imap {
Expand All @@ -15,7 +16,7 @@ impl Imap {
// First of all, debounce to once per minute:
let mut last_scan = context.last_full_folder_scan.lock().await;
if let Some(last_scan) = *last_scan {
let elapsed_secs = last_scan.elapsed().as_secs();
let elapsed_secs = time_elapsed(&last_scan).as_secs();
let debounce_secs = context
.get_config_u64(Config::ScanAllFoldersDebounceSecs)
.await?;
Expand Down Expand Up @@ -93,7 +94,7 @@ impl Imap {
.await?;
}

last_scan.replace(Instant::now());
last_scan.replace(tools::Time::now());
Ok(true)
}

Expand Down
16 changes: 12 additions & 4 deletions src/imex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ async fn export_backup(context: &Context, dir: &Path, passphrase: String) -> Res
let _d1 = DeleteOnDrop(temp_db_path.clone());
let _d2 = DeleteOnDrop(temp_path.clone());

export_database(context, &temp_db_path, passphrase)
export_database(context, &temp_db_path, passphrase, now)
.await
.context("could not export database")?;

Expand Down Expand Up @@ -770,19 +770,27 @@ where
/// overwritten.
///
/// This also verifies that IO is not running during the export.
async fn export_database(context: &Context, dest: &Path, passphrase: String) -> Result<()> {
async fn export_database(
context: &Context,
dest: &Path,
passphrase: String,
timestamp: i64,
) -> Result<()> {
ensure!(
!context.scheduler.is_running().await,
"cannot export backup, IO is running"
);
let now = time().try_into().context("32-bit UNIX time overflow")?;
let timestamp = timestamp.try_into().context("32-bit UNIX time overflow")?;

// TODO: Maybe introduce camino crate for UTF-8 paths where we need them.
let dest = dest
.to_str()
.with_context(|| format!("path {} is not valid unicode", dest.display()))?;

context.sql.set_raw_config_int("backup_time", now).await?;
context
.sql
.set_raw_config_int("backup_time", timestamp)
.await?;
sql::housekeeping(context).await.log_err(context).ok();
context
.sql
Expand Down
3 changes: 2 additions & 1 deletion src/imex/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use crate::context::Context;
use crate::message::{Message, Viewtype};
use crate::qr::{self, Qr};
use crate::stock_str::backup_transfer_msg_body;
use crate::tools::time;
use crate::{e2ee, EventType};

use super::{export_database, DBFILE_BACKUP_NAME};
Expand Down Expand Up @@ -158,7 +159,7 @@ impl BackupProvider {
// Generate the token up front: we also use it to encrypt the database.
let token = AuthToken::generate();
context.emit_event(SendProgress::Started.into());
export_database(context, dbfile, token.to_string())
export_database(context, dbfile, token.to_string(), time())
.await
.context("Database export failed")?;
context.emit_event(SendProgress::DatabaseExported.into());
Expand Down
6 changes: 3 additions & 3 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::constants::KeyGenType;
use crate::context::Context;
use crate::log::LogExt;
use crate::pgp::KeyPair;
use crate::tools::EmailAddress;
use crate::tools::{self, time_elapsed, EmailAddress};

/// Convenience trait for working with keys.
///
Expand Down Expand Up @@ -204,7 +204,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
match load_keypair(context, &addr).await? {
Some(key_pair) => Ok(key_pair),
None => {
let start = std::time::SystemTime::now();
let start = tools::Time::now();
let keytype = KeyGenType::from_i32(context.get_config_int(Config::KeyGenType).await?)
.unwrap_or_default();
info!(context, "Generating keypair with type {}", keytype);
Expand All @@ -216,7 +216,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
info!(
context,
"Keypair generated in {:.3}s.",
start.elapsed().unwrap_or_default().as_secs()
time_elapsed(&start).as_secs(),
);
Ok(keypair)
}
Expand Down
10 changes: 6 additions & 4 deletions src/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ impl Kml {
match chrono::NaiveDateTime::parse_from_str(&val, "%Y-%m-%dT%H:%M:%SZ") {
Ok(res) => {
self.curr.timestamp = res.timestamp();
if self.curr.timestamp > time() {
self.curr.timestamp = time();
let now = time();
if self.curr.timestamp > now {
self.curr.timestamp = now;
}
}
Err(_err) => {
Expand Down Expand Up @@ -333,12 +334,13 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
return Ok(true);
}
let mut continue_streaming = false;
let now = time();

let chats = context
.sql
.query_map(
"SELECT id FROM chats WHERE locations_send_until>?;",
(time(),),
(now,),
|row| row.get::<_, i32>(0),
|chats| {
chats
Expand All @@ -356,7 +358,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
latitude,
longitude,
accuracy,
time(),
now,
chat_id,
ContactId::SELF,
)).await.context("Failed to store location")?;
Expand Down