use super::{
Pools,
config::PoolConfig,
thread_local::{clear_thread_pools, get_thread_pools, set_thread_pools},
};
pub struct ScopedPools {
previous: Option<Pools>,
}
impl Default for ScopedPools {
fn default() -> Self {
Self::new(Pools::default())
}
}
impl ScopedPools {
pub fn new(pools: Pools) -> Self {
let previous = get_thread_pools();
set_thread_pools(pools);
Self {
previous,
}
}
pub fn with_config(config: PoolConfig) -> Self {
Self::new(Pools::new(config.max_pool_size))
}
pub fn test() -> Self {
Self::with_config(PoolConfig::test())
}
pub fn production() -> Self {
Self::with_config(PoolConfig::production())
}
pub fn development() -> Self {
Self::with_config(PoolConfig::development())
}
}
impl Drop for ScopedPools {
fn drop(&mut self) {
match self.previous.take() {
Some(p) => set_thread_pools(p),
None => clear_thread_pools(),
}
}
}
pub fn with_scoped_pools<F, R>(pools: Pools, f: F) -> R
where
F: FnOnce() -> R,
{
let _guard = ScopedPools::new(pools);
f()
}
pub fn with_default_pools<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
let _guard = ScopedPools::default();
f()
}
pub fn with_test_pools<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
let _guard = ScopedPools::test();
f()
}
#[cfg(test)]
pub mod tests {
use super::*;
use crate::value::column::pool::thread_local::has_thread_pools;
#[test]
fn test_scoped_pools_basic() {
clear_thread_pools();
assert!(!has_thread_pools());
{
let _guard = ScopedPools::default();
assert!(has_thread_pools());
}
assert!(!has_thread_pools());
}
#[test]
fn test_scoped_pools_restore_previous() {
let initial_pools = Pools::new(8);
set_thread_pools(initial_pools);
assert!(has_thread_pools());
{
let _guard = ScopedPools::new(Pools::new(16));
assert!(has_thread_pools());
}
assert!(has_thread_pools());
clear_thread_pools();
}
#[test]
fn test_with_scoped_pools() {
clear_thread_pools();
let result = with_scoped_pools(Pools::default(), || {
assert!(has_thread_pools());
42
});
assert_eq!(result, 42);
assert!(!has_thread_pools());
}
#[test]
fn test_with_default_pools() {
clear_thread_pools();
with_default_pools(|| {
assert!(has_thread_pools());
});
assert!(!has_thread_pools());
}
#[test]
fn test_with_test_pools() {
clear_thread_pools();
with_test_pools(|| {
assert!(has_thread_pools());
});
assert!(!has_thread_pools());
}
#[test]
fn test_nested_scoped_pools() {
clear_thread_pools();
let _outer = ScopedPools::default();
assert!(has_thread_pools());
{
let _inner = ScopedPools::test();
assert!(has_thread_pools());
}
assert!(has_thread_pools());
drop(_outer);
assert!(!has_thread_pools());
}
}