pub struct ArcTester { /* private fields */ }Expand description
Thread-safe shared ownership Tester implemented using Arc
ArcTester wraps a closure in Arc<dyn Fn() -> bool + Send + Sync>,
allowing the tester to be cloned and safely shared across threads.
§Characteristics
- Shared ownership: Can be cloned
- Thread-safe: Can be sent across threads
- Lock-free overhead: Uses
Fnwithout needingMutex - Borrowing combination:
and()/or()/not()borrow&self
§Use Cases
- Multi-threaded testing scenarios
- Health checks shared across threads
- Test states requiring concurrent access
- Background monitoring tasks
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
use std::thread;
// Shared atomic counter
let counter = Arc::new(AtomicUsize::new(0));
let counter_clone = Arc::clone(&counter);
let shared = ArcTester::new(move || {
counter_clone.load(Ordering::Relaxed) <= 5
});
let clone = shared.clone();
let handle = thread::spawn(move || {
clone.test()
});
assert!(handle.join().unwrap());
counter.fetch_add(1, Ordering::Relaxed);
assert!(shared.test());§Author
Hu Haixing
Implementations§
Source§impl ArcTester
impl ArcTester
Sourcepub fn and(&self, next: &ArcTester) -> ArcTester
pub fn and(&self, next: &ArcTester) -> ArcTester
Combines this tester with another tester using logical AND
Returns a new ArcTester that returns true only when both tests
pass. Borrows &self, so the original tester remains available.
§Parameters
next- The tester to combine with
§Return Value
A new ArcTester representing logical AND
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
use std::thread;
// 模拟数据库连接池状态
let active_connections = Arc::new(AtomicUsize::new(0));
let is_pool_healthy = Arc::new(AtomicBool::new(true));
let max_connections = 50;
let conn_clone = Arc::clone(&active_connections);
let health_clone = Arc::clone(&is_pool_healthy);
// 连接池健康检查
let pool_healthy = ArcTester::new(move || {
health_clone.load(Ordering::Relaxed)
});
// 连接数检查
let conn_ok = ArcTester::new(move || {
conn_clone.load(Ordering::Relaxed) < max_connections
});
// 组合检查:连接池健康且连接数未超限
let pool_ready = pool_healthy.and(&conn_ok);
// 多线程测试
let pool_ready_clone = pool_ready.clone();
let handle = thread::spawn(move || {
pool_ready_clone.test()
});
// 初始状态应该通过
assert!(handle.join().unwrap());
assert!(pool_ready.test());
// 连接数超限
active_connections.store(60, Ordering::Relaxed);
assert!(!pool_ready.test());
// 连接池不健康
is_pool_healthy.store(false, Ordering::Relaxed);
assert!(!pool_ready.test());Sourcepub fn or(&self, next: &ArcTester) -> ArcTester
pub fn or(&self, next: &ArcTester) -> ArcTester
Combines this tester with another tester using logical OR
Returns a new ArcTester that returns true if either test passes.
Borrows &self, so the original tester remains available.
§Parameters
next- The tester to combine with
§Return Value
A new ArcTester representing logical OR
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
use std::thread;
// 模拟负载均衡器状态
let server_load = Arc::new(AtomicUsize::new(0));
let is_server_healthy = Arc::new(AtomicBool::new(true));
let max_load = 80;
let emergency_mode = Arc::new(AtomicBool::new(false));
let load_clone = Arc::clone(&server_load);
let health_clone = Arc::clone(&is_server_healthy);
let emergency_clone = Arc::clone(&emergency_mode);
// 服务器负载低
let low_load = ArcTester::new(move || {
load_clone.load(Ordering::Relaxed) < max_load
});
// 紧急模式检查
let emergency_check = ArcTester::new(move || {
emergency_clone.load(Ordering::Relaxed)
});
// 服务器健康检查
let server_healthy = ArcTester::new(move || {
health_clone.load(Ordering::Relaxed)
});
// 紧急模式或服务器健康
let can_handle_requests = emergency_check.or(&server_healthy);
// 组合条件:负载低或可以处理请求
let should_route_here = low_load.or(&can_handle_requests);
// 多线程测试
let router_clone = should_route_here.clone();
let handle = thread::spawn(move || {
router_clone.test()
});
// 初始状态:负载低且健康
assert!(handle.join().unwrap());
assert!(should_route_here.test());
// 负载高但服务器健康
server_load.store(90, Ordering::Relaxed);
assert!(should_route_here.test()); // 仍然健康
// 服务器不健康但紧急模式
is_server_healthy.store(false, Ordering::Relaxed);
emergency_mode.store(true, Ordering::Relaxed);
assert!(should_route_here.test()); // 紧急模式
// 既不健康又非紧急模式
emergency_mode.store(false, Ordering::Relaxed);
assert!(!should_route_here.test());Sourcepub fn not(&self) -> ArcTester
pub fn not(&self) -> ArcTester
Negates the result of this tester
Returns a new ArcTester that returns the opposite value of the
original test result. Borrows &self, so the original tester remains
available.
§Return Value
A new ArcTester representing logical NOT
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
use std::thread;
// 模拟任务队列状态
let pending_tasks = Arc::new(AtomicUsize::new(0));
let max_queue_size = 100;
let tasks_clone = Arc::clone(&pending_tasks);
// 队列未满
let queue_available = ArcTester::new(move || {
tasks_clone.load(Ordering::Relaxed) < max_queue_size
});
// 队列已满(取反)
let queue_full = queue_available.not();
// 多线程测试
let queue_full_clone = queue_full.clone();
let handle = thread::spawn(move || {
queue_full_clone.test()
});
// 初始状态:队列未满
pending_tasks.store(50, Ordering::Relaxed);
assert!(queue_available.test());
assert!(!handle.join().unwrap());
assert!(!queue_full.test());
// 队列接近满载
pending_tasks.store(95, Ordering::Relaxed);
assert!(queue_available.test());
assert!(!queue_full.test());
// 队列已满
pending_tasks.store(120, Ordering::Relaxed);
assert!(!queue_available.test());
assert!(queue_full.test());Sourcepub fn nand(&self, next: &ArcTester) -> ArcTester
pub fn nand(&self, next: &ArcTester) -> ArcTester
Combines this tester with another tester using logical NAND
Returns a new ArcTester that returns true unless both tests pass.
Borrows &self, so the original tester remains available.
§Parameters
next- The tester to combine with
§Return Value
A new ArcTester representing logical NAND
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread;
let flag1 = Arc::new(AtomicBool::new(true));
let flag2 = Arc::new(AtomicBool::new(true));
let flag1_clone = Arc::clone(&flag1);
let flag2_clone = Arc::clone(&flag2);
let tester1 = ArcTester::new(move || {
flag1_clone.load(Ordering::Relaxed)
});
let tester2 = ArcTester::new(move || {
flag2_clone.load(Ordering::Relaxed)
});
let nand = tester1.nand(&tester2);
// 两个都为 true 时返回 false
assert!(!nand.test());
// 至少一个为 false 时返回 true
flag1.store(false, Ordering::Relaxed);
assert!(nand.test());
// 原始 tester 仍然可用
assert!(!tester1.test());
assert!(tester2.test());Sourcepub fn xor(&self, next: &ArcTester) -> ArcTester
pub fn xor(&self, next: &ArcTester) -> ArcTester
Combines this tester with another tester using logical XOR
Returns a new ArcTester that returns true if exactly one test
passes. Borrows &self, so the original tester remains available.
§Parameters
next- The tester to combine with
§Return Value
A new ArcTester representing logical XOR
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread;
let flag1 = Arc::new(AtomicBool::new(true));
let flag2 = Arc::new(AtomicBool::new(false));
let flag1_clone = Arc::clone(&flag1);
let flag2_clone = Arc::clone(&flag2);
let tester1 = ArcTester::new(move || {
flag1_clone.load(Ordering::Relaxed)
});
let tester2 = ArcTester::new(move || {
flag2_clone.load(Ordering::Relaxed)
});
let xor = tester1.xor(&tester2);
// 一个 true 一个 false 时返回 true
assert!(xor.test());
// 两个都为 true 时返回 false
flag2.store(true, Ordering::Relaxed);
assert!(!xor.test());
// 两个都为 false 时返回 false
flag1.store(false, Ordering::Relaxed);
flag2.store(false, Ordering::Relaxed);
assert!(!xor.test());
// 原始 tester 仍然可用
assert!(!tester1.test());
assert!(!tester2.test());Sourcepub fn nor(&self, next: &ArcTester) -> ArcTester
pub fn nor(&self, next: &ArcTester) -> ArcTester
Combines this tester with another tester using logical NOR
Returns a new ArcTester that returns true only when both tests
fail. Borrows &self, so the original tester remains available.
§Parameters
next- The tester to combine with
§Return Value
A new ArcTester representing logical NOR
§Examples
use prism3_function::{ArcTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread;
let flag1 = Arc::new(AtomicBool::new(false));
let flag2 = Arc::new(AtomicBool::new(false));
let flag1_clone = Arc::clone(&flag1);
let flag2_clone = Arc::clone(&flag2);
let tester1 = ArcTester::new(move || {
flag1_clone.load(Ordering::Relaxed)
});
let tester2 = ArcTester::new(move || {
flag2_clone.load(Ordering::Relaxed)
});
let nor = tester1.nor(&tester2);
// 两个都为 false 时返回 true
assert!(nor.test());
// 至少一个为 true 时返回 false
flag1.store(true, Ordering::Relaxed);
assert!(!nor.test());
// 原始 tester 仍然可用
assert!(tester1.test());
assert!(!tester2.test());