Skip to main content

tsoracle_yieldpoint/
lib.rs

1//
2//  ░▀█▀░█▀▀░█▀█░█▀▄░█▀█░█▀▀░█░░░█▀▀
3//  ░░█░░▀▀█░█░█░█▀▄░█▀█░█░░░█░░░█▀▀
4//  ░░▀░░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀▀▀░▀▀▀
5//
6//  tsoracle — Distributed Timestamp Oracle
7//  https://www.tsoracle.rs
8//
9//  Copyright (c) 2026 Prisma Risk
10//
11//  Licensed under the Apache License, Version 2.0 (the "License");
12//  you may not use this file except in compliance with the License.
13//  You may obtain a copy of the License at
14//
15//      https://www.apache.org/licenses/LICENSE-2.0
16//
17//  Unless required by applicable law or agreed to in writing, software
18//  distributed under the License is distributed on an "AS IS" BASIS,
19//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20//  See the License for the specific language governing permissions and
21//  limitations under the License.
22//
23
24#![doc = include_str!("../README.md")]
25
26#[cfg(feature = "yieldpoints")]
27mod registry {
28    use std::collections::HashMap;
29    use std::sync::Arc;
30    use std::sync::OnceLock;
31
32    use parking_lot::Mutex;
33    use tokio::sync::Notify;
34
35    fn store() -> &'static Mutex<HashMap<&'static str, Arc<Notify>>> {
36        static STORE: OnceLock<Mutex<HashMap<&'static str, Arc<Notify>>>> = OnceLock::new();
37        STORE.get_or_init(|| Mutex::new(HashMap::new()))
38    }
39
40    /// Arm `name`. The returned handle is shared with the
41    /// [`yieldpoint!`](crate::yieldpoint) call site; wake the production
42    /// code by calling `notify_one()` on it.
43    pub fn cfg(name: &'static str) -> Arc<Notify> {
44        let notify = Arc::new(Notify::new());
45        store().lock().insert(name, notify.clone());
46        notify
47    }
48
49    /// Clear the armed entry for `name`. The yield point expands to a
50    /// no-op on subsequent invocations until armed again.
51    pub fn remove(name: &'static str) {
52        store().lock().remove(name);
53    }
54
55    /// Lookup used by the [`yieldpoint!`](crate::yieldpoint) macro.
56    #[doc(hidden)]
57    pub fn get(name: &'static str) -> Option<Arc<Notify>> {
58        store().lock().get(name).cloned()
59    }
60}
61
62#[cfg(feature = "yieldpoints")]
63pub use registry::{cfg, get, remove};
64
65/// Await the registered `Notify` at this site if armed; no-op otherwise.
66///
67/// Expands to `{}` when the `yieldpoints` cargo feature is off (on
68/// `yield-rs` itself), so production builds of consuming crates carry
69/// zero overhead. When on, an armed entry parks the calling task on
70/// `Notify::notified().await` — yielding the tokio worker so timers and
71/// other tasks continue to run. Release with `notify_one()` on the
72/// handle returned by [`cfg`](cfg()).
73#[cfg(feature = "yieldpoints")]
74#[macro_export]
75macro_rules! yieldpoint {
76    ($name:expr) => {{
77        if let Some(yp) = $crate::get($name) {
78            yp.notified().await;
79        }
80    }};
81}
82
83#[cfg(not(feature = "yieldpoints"))]
84#[macro_export]
85macro_rules! yieldpoint {
86    ($name:expr) => {{}};
87}