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}