/build/source/nativelink-util/src/instant_wrapper.rs
Line | Count | Source |
1 | | // Copyright 2024 The NativeLink Authors. All rights reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | use core::future::Future; |
16 | | use core::time::Duration; |
17 | | use std::time::{SystemTime, UNIX_EPOCH}; |
18 | | |
19 | | use mock_instant::thread_local::{Instant as MockInstant, MockClock}; |
20 | | |
21 | | /// Wrapper used to abstract away which underlying Instant impl we are using. |
22 | | /// This is needed for testing. |
23 | | pub trait InstantWrapper: Send + Sync + Unpin + 'static { |
24 | | fn from_secs(secs: u64) -> Self; |
25 | | fn unix_timestamp(&self) -> u64; |
26 | | fn now(&self) -> SystemTime; |
27 | | fn elapsed(&self) -> Duration; |
28 | | fn sleep(self, duration: Duration) -> impl Future<Output = ()> + Send + Sync + 'static; |
29 | | } |
30 | | |
31 | | impl InstantWrapper for SystemTime { |
32 | 0 | fn from_secs(secs: u64) -> Self { |
33 | 0 | Self::UNIX_EPOCH |
34 | 0 | .checked_add(Duration::from_secs(secs)) |
35 | 0 | .unwrap() |
36 | 0 | } |
37 | | |
38 | 2 | fn unix_timestamp(&self) -> u64 { |
39 | 2 | self.duration_since(UNIX_EPOCH).unwrap().as_secs() |
40 | 2 | } |
41 | | |
42 | 0 | fn now(&self) -> SystemTime { |
43 | 0 | Self::now() |
44 | 0 | } |
45 | | |
46 | 20.9k | fn elapsed(&self) -> Duration { |
47 | 20.9k | <Self>::elapsed(self).unwrap() |
48 | 20.9k | } |
49 | | |
50 | 0 | async fn sleep(self, duration: Duration) { |
51 | 0 | tokio::time::sleep(duration).await; |
52 | 0 | } |
53 | | } |
54 | | |
55 | 0 | pub fn default_instant_wrapper() -> impl InstantWrapper { |
56 | 0 | SystemTime::now() |
57 | 0 | } |
58 | | |
59 | | /// Our mocked out instant that we can pass to our `EvictionMap`. |
60 | | #[derive(Debug, Clone, Copy)] |
61 | | pub struct MockInstantWrapped(MockInstant); |
62 | | |
63 | | impl Default for MockInstantWrapped { |
64 | 986 | fn default() -> Self { |
65 | 986 | Self(MockInstant::now()) |
66 | 986 | } |
67 | | } |
68 | | |
69 | | impl InstantWrapper for MockInstantWrapped { |
70 | 32 | fn from_secs(_secs: u64) -> Self { |
71 | 32 | Self(MockInstant::now()) |
72 | 32 | } |
73 | | |
74 | 4 | fn unix_timestamp(&self) -> u64 { |
75 | 4 | MockClock::time().as_secs() |
76 | 4 | } |
77 | | |
78 | 671 | fn now(&self) -> SystemTime { |
79 | 671 | UNIX_EPOCH + MockClock::time() |
80 | 671 | } |
81 | | |
82 | 457 | fn elapsed(&self) -> Duration { |
83 | 457 | self.0.elapsed() |
84 | 457 | } |
85 | | |
86 | 170 | async fn sleep(self, duration: Duration)0 { |
87 | 170 | let baseline = self.0.elapsed(); |
88 | | loop { |
89 | 3.03k | tokio::task::yield_now().await; |
90 | 2.97k | if self.0.elapsed() - baseline >= duration { Branch (90:16): [Folded - Ignored]
Branch (90:16): [Folded - Ignored]
Branch (90:16): [True: 0, False: 1]
Branch (90:16): [True: 115, False: 2.86k]
|
91 | 115 | break; |
92 | 2.86k | } |
93 | | } |
94 | 115 | } |
95 | | } |