chore: clean up up warning behavior for resources that depend on other resources (#4415) (closes #3372)

This commit is contained in:
Greg Johnston
2025-11-17 21:00:41 -05:00
committed by GitHub
parent eec9edf517
commit 83a848b5ec
2 changed files with 58 additions and 11 deletions

View File

@@ -188,6 +188,39 @@ where
}
}
#[cfg(debug_assertions)]
thread_local! {
static RESOURCE_SOURCE_SIGNAL_ACTIVE: AtomicBool = const { AtomicBool::new(false) };
}
#[cfg(debug_assertions)]
/// Returns whether the current thread is currently running a resource source signal.
pub fn in_resource_source_signal() -> bool {
RESOURCE_SOURCE_SIGNAL_ACTIVE
.with(|scope| scope.load(std::sync::atomic::Ordering::Relaxed))
}
/// Set a static to true whilst running the given function.
/// [`is_in_effect_scope`] will return true whilst the function is running.
fn run_in_resource_source_signal<T>(fun: impl FnOnce() -> T) -> T {
#[cfg(debug_assertions)]
{
// For the theoretical nested case, set back to initial value rather than false:
let initial = RESOURCE_SOURCE_SIGNAL_ACTIVE.with(|scope| {
scope.swap(true, std::sync::atomic::Ordering::Relaxed)
});
let result = fun();
RESOURCE_SOURCE_SIGNAL_ACTIVE.with(|scope| {
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
});
result
}
#[cfg(not(debug_assertions))]
{
fun()
}
}
impl<T, Ser> ReadUntracked for ArcResource<T, Ser>
where
T: 'static,
@@ -202,7 +235,9 @@ where
computed::suspense::SuspenseContext, effect::in_effect_scope,
owner::use_context,
};
if !in_effect_scope() && use_context::<SuspenseContext>().is_none()
if !in_effect_scope()
&& !in_resource_source_signal()
&& use_context::<SuspenseContext>().is_none()
{
let location = std::panic::Location::caller();
reactive_graph::log_warning(format_args!(
@@ -271,7 +306,7 @@ where
let refetch = ArcRwSignal::new(0);
let source = ArcMemo::new({
let refetch = refetch.clone();
move |_| (refetch.get(), source())
move |_| (refetch.get(), run_in_resource_source_signal(&source))
});
let fun = {
let source = source.clone();
@@ -909,7 +944,9 @@ where
computed::suspense::SuspenseContext, effect::in_effect_scope,
owner::use_context,
};
if !in_effect_scope() && use_context::<SuspenseContext>().is_none()
if !in_effect_scope()
&& !in_resource_source_signal()
&& use_context::<SuspenseContext>().is_none()
{
let location = std::panic::Location::caller();
reactive_graph::log_warning(format_args!(

View File

@@ -110,10 +110,12 @@ fn effect_base() -> (Receiver, Owner, Arc<RwLock<EffectInner>>) {
(rx, owner, inner)
}
#[cfg(debug_assertions)]
thread_local! {
static EFFECT_SCOPE_ACTIVE: AtomicBool = const { AtomicBool::new(false) };
}
#[cfg(debug_assertions)]
/// Returns whether the current thread is currently running an effect.
pub fn in_effect_scope() -> bool {
EFFECT_SCOPE_ACTIVE
@@ -123,14 +125,22 @@ pub fn in_effect_scope() -> bool {
/// Set a static to true whilst running the given function.
/// [`is_in_effect_scope`] will return true whilst the function is running.
fn run_in_effect_scope<T>(fun: impl FnOnce() -> T) -> T {
// For the theoretical nested case, set back to initial value rather than false:
let initial = EFFECT_SCOPE_ACTIVE
.with(|scope| scope.swap(true, std::sync::atomic::Ordering::Relaxed));
let result = fun();
EFFECT_SCOPE_ACTIVE.with(|scope| {
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
});
result
#[cfg(debug_assertions)]
{
// For the theoretical nested case, set back to initial value rather than false:
let initial = EFFECT_SCOPE_ACTIVE.with(|scope| {
scope.swap(true, std::sync::atomic::Ordering::Relaxed)
});
let result = fun();
EFFECT_SCOPE_ACTIVE.with(|scope| {
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
});
result
}
#[cfg(not(debug_assertions))]
{
fun()
}
}
impl<S> Effect<S>