Skip to content

Commit 140ba9f

Browse files
authored
refactor: use Instant instead of Utc in checking.rs (#60)
Since we're just measuring elapsed time, `Instant` is the correct type to use, since it's monotonic whenever possible and will also play nicely with mocked time for tests.
2 parents 1bb1665 + a340de8 commit 140ba9f

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

src/checking.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ use axum::{
1818
body::Bytes,
1919
http::{Uri, uri::Scheme},
2020
};
21-
use chrono::Utc;
2221
use futures::{Stream, TryStreamExt};
2322
use reqwest::{Client, Response, StatusCode};
2423
use sarlacc::Intern;
25-
use tokio::sync::RwLock;
24+
use tokio::{sync::RwLock, time::Instant};
2625
use tracing::{error, info, instrument};
2726

2827
use crate::{discord::Snowflake, webring::CheckLevel};
@@ -32,8 +31,8 @@ use crate::{discord::Snowflake, webring::CheckLevel};
3231
#[allow(clippy::unreadable_literal)]
3332
const WEBRING_CHANNEL: Snowflake = Snowflake::new(1319140464812753009);
3433

35-
/// The time in milliseconds for which the server is considered online after a successful ping.
36-
const ONLINE_CHECK_TTL_MS: i64 = 1000;
34+
/// The time for which the server is considered online after a successful ping.
35+
const ONLINE_CHECK_TTL: Duration = Duration::from_secs(1);
3736

3837
/// The timeout to retry requesting a site after failure
3938
const RETRY_TIMEOUT: Duration = Duration::from_secs(5);
@@ -59,28 +58,32 @@ static CLIENT: LazyLock<Client> = LazyLock::new(|| {
5958
});
6059

6160
/// (Last pinged, Was ping successful) — Used to check if the server is online
62-
static PING_INFO: RwLock<(i64, bool)> = RwLock::const_new((i64::MIN, false));
61+
static PING_INFO: RwLock<(Option<Instant>, bool)> = RwLock::const_new((None, false));
6362

6463
/// If a request succeeds, then call this function to mark the server as definitely online.
6564
async fn mark_server_as_online() {
66-
let at = Utc::now().timestamp_millis();
65+
let at = Instant::now();
6766
let mut ping_info = PING_INFO.write().await;
68-
let now = Utc::now().timestamp_millis();
67+
let now = Instant::now();
6968

70-
if at + ONLINE_CHECK_TTL_MS < now || ping_info.0 > at {
69+
if at + ONLINE_CHECK_TTL < now || ping_info.0.is_some_and(|ping| ping > at) {
7170
return;
7271
}
7372

74-
*ping_info = (at, true);
73+
*ping_info = (Some(at), true);
7574
}
7675

77-
/// Check if the server is online by either getting a cached value (cached for `ONLINE_CHECK_TTL_MS`), or by requesting our repository.
76+
/// Check if the server is online by either getting a cached value (cached for
77+
/// [`ONLINE_CHECK_TTL`]), or by making a `HEAD` request to the repository URL.
7878
async fn is_online() -> bool {
7979
{
8080
// Has it been checked within the TTL?
8181
let ping_info = PING_INFO.read().await;
82-
let now = Utc::now().timestamp_millis();
83-
if now < ping_info.0 + ONLINE_CHECK_TTL_MS {
82+
let now = Instant::now();
83+
if ping_info
84+
.0
85+
.is_some_and(|ping| now < ping + ONLINE_CHECK_TTL)
86+
{
8487
return ping_info.1;
8588
}
8689
}
@@ -89,22 +92,25 @@ async fn is_online() -> bool {
8992
let mut ping_info = PING_INFO.write().await;
9093

9194
// What if another thread did the ping while we were waiting for the write lock? If so, return it.
92-
let now = Utc::now().timestamp_millis();
93-
if now < ping_info.0 + ONLINE_CHECK_TTL_MS {
95+
let now = Instant::now();
96+
if ping_info
97+
.0
98+
.is_some_and(|ping| now < ping + ONLINE_CHECK_TTL)
99+
{
94100
return ping_info.1;
95101
}
96102

97103
// Head-request our repository to make sure we're online.
98-
let result = CLIENT
104+
let ping_successful = CLIENT
99105
.head(env!("CARGO_PKG_REPOSITORY"))
100106
.send()
101107
.await
102-
.and_then(Response::error_for_status);
103-
let ping_successful = result.is_ok();
108+
.and_then(Response::error_for_status)
109+
.is_ok();
104110

105111
// Write the info
106-
let now = Utc::now().timestamp_millis();
107-
*ping_info = (now, ping_successful);
112+
let now = Instant::now();
113+
*ping_info = (Some(now), ping_successful);
108114

109115
ping_successful
110116
}

0 commit comments

Comments
 (0)