diff --git a/Cargo.lock b/Cargo.lock index 340b4fc..71e12f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,21 +43,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anyhow" version = "1.0.75" @@ -147,13 +132,8 @@ version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", - "windows-targets", ] [[package]] @@ -188,7 +168,7 @@ dependencies = [ [[package]] name = "denokv_remote" -version = "0.2.2" +version = "0.2.3" dependencies = [ "anyhow", "async-trait", @@ -208,7 +188,7 @@ dependencies = [ [[package]] name = "denokv_sqlite" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "async-trait", @@ -523,29 +503,6 @@ dependencies = [ "want", ] -[[package]] -name = "iana-time-zone" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "idna" version = "0.4.0" @@ -1449,15 +1406,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index dad51dc..969fa4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ denokv_proto = { version = "0.2.0", path = "./proto" } anyhow = "1" async-trait = "0.1" bytes = "1" -chrono = { version = "0.4", features = ["serde"] } +chrono = { version = "0.4", default-features = false, features = ["std", "serde"] } futures = "0.3.28" log = "0.4.20" num-bigint = "0.4" diff --git a/proto/lib.rs b/proto/lib.rs index b7c42d8..39d40ae 100644 --- a/proto/lib.rs +++ b/proto/lib.rs @@ -1,3 +1,5 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + mod codec; mod interface; mod protobuf; diff --git a/remote/Cargo.toml b/remote/Cargo.toml index 670a51b..b4c6f9d 100644 --- a/remote/Cargo.toml +++ b/remote/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "denokv_remote" description = "Remote (KV Connect) backend for Deno KV" -version = "0.2.2" +version = "0.2.3" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/remote/lib.rs b/remote/lib.rs index 9363427..94761a9 100644 --- a/remote/lib.rs +++ b/remote/lib.rs @@ -1,3 +1,7 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + +mod time; + use std::ops::Sub; use std::sync::Arc; use std::time::Duration; @@ -25,6 +29,7 @@ use log::warn; use rand::Rng; use reqwest::StatusCode; use serde::Deserialize; +use time::utc_now; use tokio::sync::watch; use tokio::task::JoinHandle; use url::Url; @@ -231,15 +236,15 @@ async fn metadata_refresh_task( match res { RetryableResult::Ok(metadata) => { attempts = 0; - let expires_in = metadata.expires_at.signed_duration_since(Utc::now()); + let expires_in = metadata.expires_at.signed_duration_since(utc_now()); if tx.send(MetadataState::Ok(Arc::new(metadata))).is_err() { // The receiver has been dropped, so we can stop now. return; } - // Sleep until the token expires, minus a 10 minute buffer, but at minimum - // one minute. + // Sleep until the token expires, minus a 10 minute buffer, but at + // minimum one minute. let sleep_time = expires_in .sub(chrono::Duration::seconds(10)) .to_std() diff --git a/remote/time.rs b/remote/time.rs new file mode 100644 index 0000000..1a56e80 --- /dev/null +++ b/remote/time.rs @@ -0,0 +1,19 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + +/// Identical to chrono::Utc::now() but without the system "clock" +/// feature flag. +/// +/// The "clock" feature flag pulls in the "iana-time-zone" crate +/// which links to macOS's "CoreFoundation" framework which increases +/// startup time for the CLI. +pub fn utc_now() -> chrono::DateTime { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("system time before Unix epoch"); + let naive = chrono::NaiveDateTime::from_timestamp_opt( + now.as_secs() as i64, + now.subsec_nanos(), + ) + .unwrap(); + chrono::DateTime::from_naive_utc_and_offset(naive, chrono::Utc) +} diff --git a/sqlite/Cargo.toml b/sqlite/Cargo.toml index 11eab9b..b8e9526 100644 --- a/sqlite/Cargo.toml +++ b/sqlite/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "denokv_sqlite" description = "SQLite storage backend for Deno KV" -version = "0.2.0" +version = "0.2.1" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/sqlite/backend.rs b/sqlite/backend.rs index 38ca496..71e0bfa 100644 --- a/sqlite/backend.rs +++ b/sqlite/backend.rs @@ -1,3 +1,5 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + use std::collections::HashSet; use std::sync::Arc; use std::time::Duration; @@ -24,6 +26,8 @@ use rusqlite::OptionalExtension; use rusqlite::Transaction; use uuid::Uuid; +use crate::time::utc_now; + const STATEMENT_INC_AND_GET_DATA_VERSION: &str = "update data_version set version = version + ? where k = 0 returning version"; const STATEMENT_KV_RANGE_SCAN: &str = @@ -343,7 +347,7 @@ impl SqliteBackend { pub fn queue_running_keepalive(&mut self) -> Result<(), anyhow::Error> { let running_messages = self.messages_running.clone(); - let now = Utc::now(); + let now = utc_now(); self.run_tx(|tx, _| { let mut update_deadline_stmt = tx.prepare_cached(STATEMENT_QUEUE_UPDATE_RUNNING_DEADLINE)?; @@ -360,7 +364,7 @@ impl SqliteBackend { } pub fn queue_cleanup(&mut self) -> Result<(), anyhow::Error> { - let now = Utc::now(); + let now = utc_now(); let queue_dequeue_waker = self.dequeue_notify.clone(); loop { let done = self.run_tx(|tx, rng| { @@ -389,7 +393,7 @@ impl SqliteBackend { &mut self, ) -> Result<(Option, Option>), anyhow::Error> { - let now = Utc::now(); + let now = utc_now(); let can_dispatch = self.messages_running.len() < DISPATCH_CONCURRENCY_LIMIT; @@ -476,7 +480,7 @@ impl SqliteBackend { id: &QueueMessageId, success: bool, ) -> Result<(), anyhow::Error> { - let now = Utc::now(); + let now = utc_now(); let requeued = self.run_tx(|tx, rng| { let requeued = if success { let changed = tx @@ -498,7 +502,7 @@ impl SqliteBackend { pub fn collect_expired( &mut self, ) -> Result>, anyhow::Error> { - let now = Utc::now(); + let now = utc_now(); self.run_tx(|tx, _| { tx.prepare_cached(STATEMENT_DELETE_ALL_EXPIRED)? .execute(params![now.timestamp_millis()])?; diff --git a/sqlite/lib.rs b/sqlite/lib.rs index 39f9643..f48c6ae 100644 --- a/sqlite/lib.rs +++ b/sqlite/lib.rs @@ -1,4 +1,7 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + mod backend; +mod time; use std::collections::VecDeque; use std::ops::Add; @@ -24,6 +27,7 @@ use denokv_proto::SnapshotReadOptions; use futures::future::Either; use rand::RngCore; pub use rusqlite::Connection; +use time::utc_now; use tokio::select; use tokio::sync::oneshot; use tokio::sync::Notify; @@ -109,7 +113,7 @@ async fn sqlite_thread( dequeue_notify: Arc, mut request_rx: tokio::sync::mpsc::Receiver, ) { - let start = Utc::now(); + let start = utc_now(); if let Err(err) = backend.queue_cleanup() { panic!("KV queue cleanup failed: {err}"); } @@ -138,7 +142,7 @@ async fn sqlite_thread( EXPIRY_JITTER, ); loop { - let now = Utc::now(); + let now = utc_now(); let mut closest_deadline = queue_cleanup_deadline .min(queue_keepalive_deadline) .min(expiry_deadline); @@ -245,7 +249,7 @@ fn compute_deadline_with_max_and_jitter( max: Duration, jitter_duration: Duration, ) -> DateTime { - let fallback = Utc::now() + max; + let fallback = utc_now() + max; next_ready.unwrap_or(fallback).min(fallback) + duration_with_total_jitter(jitter_duration) } diff --git a/sqlite/time.rs b/sqlite/time.rs new file mode 100644 index 0000000..1a56e80 --- /dev/null +++ b/sqlite/time.rs @@ -0,0 +1,19 @@ +// Copyright 2023 the Deno authors. All rights reserved. MIT license. + +/// Identical to chrono::Utc::now() but without the system "clock" +/// feature flag. +/// +/// The "clock" feature flag pulls in the "iana-time-zone" crate +/// which links to macOS's "CoreFoundation" framework which increases +/// startup time for the CLI. +pub fn utc_now() -> chrono::DateTime { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("system time before Unix epoch"); + let naive = chrono::NaiveDateTime::from_timestamp_opt( + now.as_secs() as i64, + now.subsec_nanos(), + ) + .unwrap(); + chrono::DateTime::from_naive_utc_and_offset(naive, chrono::Utc) +}