Skip to content

Commit ceb7195

Browse files
gbjmaccesch
authored andcommitted
chore: clean up up warning behavior for resources that depend on other resources (leptos-rs#4415) (closes leptos-rs#3372)
1 parent c65f576 commit ceb7195

File tree

2 files changed

+58
-11
lines changed

2 files changed

+58
-11
lines changed

leptos_server/src/resource.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,39 @@ where
188188
}
189189
}
190190

191+
#[cfg(debug_assertions)]
192+
thread_local! {
193+
static RESOURCE_SOURCE_SIGNAL_ACTIVE: AtomicBool = const { AtomicBool::new(false) };
194+
}
195+
196+
#[cfg(debug_assertions)]
197+
/// Returns whether the current thread is currently running a resource source signal.
198+
pub fn in_resource_source_signal() -> bool {
199+
RESOURCE_SOURCE_SIGNAL_ACTIVE
200+
.with(|scope| scope.load(std::sync::atomic::Ordering::Relaxed))
201+
}
202+
203+
/// Set a static to true whilst running the given function.
204+
/// [`is_in_effect_scope`] will return true whilst the function is running.
205+
fn run_in_resource_source_signal<T>(fun: impl FnOnce() -> T) -> T {
206+
#[cfg(debug_assertions)]
207+
{
208+
// For the theoretical nested case, set back to initial value rather than false:
209+
let initial = RESOURCE_SOURCE_SIGNAL_ACTIVE.with(|scope| {
210+
scope.swap(true, std::sync::atomic::Ordering::Relaxed)
211+
});
212+
let result = fun();
213+
RESOURCE_SOURCE_SIGNAL_ACTIVE.with(|scope| {
214+
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
215+
});
216+
result
217+
}
218+
#[cfg(not(debug_assertions))]
219+
{
220+
fun()
221+
}
222+
}
223+
191224
impl<T, Ser> ReadUntracked for ArcResource<T, Ser>
192225
where
193226
T: 'static,
@@ -202,7 +235,9 @@ where
202235
computed::suspense::SuspenseContext, effect::in_effect_scope,
203236
owner::use_context,
204237
};
205-
if !in_effect_scope() && use_context::<SuspenseContext>().is_none()
238+
if !in_effect_scope()
239+
&& !in_resource_source_signal()
240+
&& use_context::<SuspenseContext>().is_none()
206241
{
207242
let location = std::panic::Location::caller();
208243
reactive_graph::log_warning(format_args!(
@@ -271,7 +306,7 @@ where
271306
let refetch = ArcRwSignal::new(0);
272307
let source = ArcMemo::new({
273308
let refetch = refetch.clone();
274-
move |_| (refetch.get(), source())
309+
move |_| (refetch.get(), run_in_resource_source_signal(&source))
275310
});
276311
let fun = {
277312
let source = source.clone();
@@ -909,7 +944,9 @@ where
909944
computed::suspense::SuspenseContext, effect::in_effect_scope,
910945
owner::use_context,
911946
};
912-
if !in_effect_scope() && use_context::<SuspenseContext>().is_none()
947+
if !in_effect_scope()
948+
&& !in_resource_source_signal()
949+
&& use_context::<SuspenseContext>().is_none()
913950
{
914951
let location = std::panic::Location::caller();
915952
reactive_graph::log_warning(format_args!(

reactive_graph/src/effect/effect.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,12 @@ fn effect_base() -> (Receiver, Owner, Arc<RwLock<EffectInner>>) {
110110
(rx, owner, inner)
111111
}
112112

113+
#[cfg(debug_assertions)]
113114
thread_local! {
114115
static EFFECT_SCOPE_ACTIVE: AtomicBool = const { AtomicBool::new(false) };
115116
}
116117

118+
#[cfg(debug_assertions)]
117119
/// Returns whether the current thread is currently running an effect.
118120
pub fn in_effect_scope() -> bool {
119121
EFFECT_SCOPE_ACTIVE
@@ -123,14 +125,22 @@ pub fn in_effect_scope() -> bool {
123125
/// Set a static to true whilst running the given function.
124126
/// [`is_in_effect_scope`] will return true whilst the function is running.
125127
fn run_in_effect_scope<T>(fun: impl FnOnce() -> T) -> T {
126-
// For the theoretical nested case, set back to initial value rather than false:
127-
let initial = EFFECT_SCOPE_ACTIVE
128-
.with(|scope| scope.swap(true, std::sync::atomic::Ordering::Relaxed));
129-
let result = fun();
130-
EFFECT_SCOPE_ACTIVE.with(|scope| {
131-
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
132-
});
133-
result
128+
#[cfg(debug_assertions)]
129+
{
130+
// For the theoretical nested case, set back to initial value rather than false:
131+
let initial = EFFECT_SCOPE_ACTIVE.with(|scope| {
132+
scope.swap(true, std::sync::atomic::Ordering::Relaxed)
133+
});
134+
let result = fun();
135+
EFFECT_SCOPE_ACTIVE.with(|scope| {
136+
scope.store(initial, std::sync::atomic::Ordering::Relaxed)
137+
});
138+
result
139+
}
140+
#[cfg(not(debug_assertions))]
141+
{
142+
fun()
143+
}
134144
}
135145

136146
impl<S> Effect<S>

0 commit comments

Comments
 (0)