Skip to content

Commit 880cf8e

Browse files
authored
Implement re_tuid::Tuid::random() on web (#1796)
* Implement `re_tuid::Tuid::random()` on web * Fix bad error message
1 parent 8ab1155 commit 880cf8e

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/re_tuid/Cargo.toml

+2-4
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,15 @@ serde = ["dep:serde"]
2828

2929
[dependencies]
3030
document-features = "0.2"
31+
getrandom = "0.2"
32+
instant = "0.1"
3133
once_cell = "1.16"
3234

3335
# Optional dependencies:
3436
arrow2 = { workspace = true, optional = true } # used by arrow2_convert
3537
arrow2_convert = { workspace = true, optional = true }
3638
serde = { version = "1", features = ["derive"], optional = true }
3739

38-
# native dependencies:
39-
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
40-
getrandom = "0.2"
41-
4240
[dev-dependencies]
4341
criterion = "0.4"
4442

crates/re_tuid/src/lib.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ impl Tuid {
6161
};
6262

6363
#[inline]
64-
#[cfg(not(target_arch = "wasm32"))] // TODO(emilk): implement for wasm32 (needs ms since epoch).
6564
pub fn random() -> Self {
6665
use std::cell::RefCell;
6766

@@ -106,35 +105,39 @@ impl Tuid {
106105

107106
/// Returns a high-precision, monotonically increasing count that approximates nanoseconds since unix epoch.
108107
#[inline]
109-
#[cfg(not(target_arch = "wasm32"))]
110108
fn monotonic_nanos_since_epoch() -> u64 {
111109
// This can maybe be optimized
110+
use instant::Instant;
112111
use once_cell::sync::Lazy;
113-
use std::time::Instant;
114-
115-
fn epoch_offset_and_start() -> (u64, Instant) {
116-
if let Ok(duration_since_epoch) = std::time::UNIX_EPOCH.elapsed() {
117-
let nanos_since_epoch = duration_since_epoch.as_nanos() as u64;
118-
(nanos_since_epoch, Instant::now())
119-
} else {
120-
// system time is set before 1970. this should be quite rare.
121-
(0, Instant::now())
122-
}
123-
}
124112

125-
static START_TIME: Lazy<(u64, Instant)> = Lazy::new(epoch_offset_and_start);
113+
static START_TIME: Lazy<(u64, Instant)> = Lazy::new(|| (nanos_since_epoch(), Instant::now()));
126114
START_TIME.0 + START_TIME.1.elapsed().as_nanos() as u64
127115
}
128116

117+
fn nanos_since_epoch() -> u64 {
118+
if let Ok(duration_since_epoch) = instant::SystemTime::UNIX_EPOCH.elapsed() {
119+
let mut nanos_since_epoch = duration_since_epoch.as_nanos() as u64;
120+
121+
if cfg!(target_arch = "wasm32") {
122+
// Web notriously round to the nearest millisecond (because of spectre/meltdown)
123+
// so we add a bit of extra randomenss here to increase our entropy and reduce the chance of collisions:
124+
nanos_since_epoch += random_u64() % 1_000_000;
125+
}
126+
127+
nanos_since_epoch
128+
} else {
129+
// system time is set before 1970. this should be quite rare.
130+
0
131+
}
132+
}
133+
129134
#[inline]
130-
#[cfg(not(target_arch = "wasm32"))]
131135
fn random_u64() -> u64 {
132136
let mut bytes = [0_u8; 8];
133-
getrandom::getrandom(&mut bytes).expect("Couldn't get inc");
137+
getrandom::getrandom(&mut bytes).expect("Couldn't get random bytes");
134138
u64::from_le_bytes(bytes)
135139
}
136140

137-
#[cfg(not(target_arch = "wasm32"))]
138141
#[test]
139142
fn test_tuid() {
140143
use std::collections::{BTreeSet, HashSet};

0 commit comments

Comments
 (0)