Skip to content

Commit

Permalink
fix: panic during generate_route_list if you immediately dispatch a…
Browse files Browse the repository at this point in the history
…n action (leptos-rs#1853)
  • Loading branch information
gbj authored and maccesch committed Oct 7, 2023
1 parent 8b9fdd6 commit d118496
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 49 deletions.
5 changes: 5 additions & 0 deletions leptos_reactive/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,11 @@ pub fn suppress_resource_load(suppress: bool) {
SUPPRESS_RESOURCE_LOAD.with(|w| w.set(suppress));
}

#[doc(hidden)]
pub fn is_suppressing_resource_load() -> bool {
SUPPRESS_RESOURCE_LOAD.with(|w| w.get())
}

impl<S, T> SignalDispose for Resource<S, T>
where
S: 'static,
Expand Down
50 changes: 26 additions & 24 deletions leptos_server/src/action.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{ServerFn, ServerFnError};
use leptos_reactive::{
batch, create_rw_signal, signal_prelude::*, spawn_local, store_value,
ReadSignal, RwSignal, StoredValue,
batch, create_rw_signal, is_suppressing_resource_load, signal_prelude::*,
spawn_local, store_value, ReadSignal, RwSignal, StoredValue,
};
use std::{cell::Cell, future::Future, pin::Pin, rc::Rc};

Expand Down Expand Up @@ -228,28 +228,30 @@ where
tracing::instrument(level = "trace", skip_all,)
)]
pub fn dispatch(&self, input: I) {
let fut = (self.action_fn)(&input);
self.input.set(Some(input));
let input = self.input;
let version = self.version;
let pending = self.pending;
let pending_dispatches = Rc::clone(&self.pending_dispatches);
let value = self.value;
pending.set(true);
pending_dispatches.set(pending_dispatches.get().saturating_sub(1));
spawn_local(async move {
let new_value = fut.await;
batch(move || {
value.set(Some(new_value));
input.set(None);
version.update(|n| *n += 1);
pending_dispatches
.set(pending_dispatches.get().saturating_sub(1));
if pending_dispatches.get() == 0 {
pending.set(false);
}
});
})
if !is_suppressing_resource_load() {
let fut = (self.action_fn)(&input);
self.input.set(Some(input));
let input = self.input;
let version = self.version;
let pending = self.pending;
let pending_dispatches = Rc::clone(&self.pending_dispatches);
let value = self.value;
pending.set(true);
pending_dispatches.set(pending_dispatches.get().saturating_sub(1));
spawn_local(async move {
let new_value = fut.await;
batch(move || {
value.set(Some(new_value));
input.set(None);
version.update(|n| *n += 1);
pending_dispatches
.set(pending_dispatches.get().saturating_sub(1));
if pending_dispatches.get() == 0 {
pending.set(false);
}
});
})
}
}
}

Expand Down
52 changes: 27 additions & 25 deletions leptos_server/src/multi_action.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{ServerFn, ServerFnError};
use leptos_reactive::{
create_rw_signal, signal_prelude::*, spawn_local, store_value, untrack,
ReadSignal, RwSignal, StoredValue,
create_rw_signal, is_suppressing_resource_load, signal_prelude::*,
spawn_local, store_value, untrack, ReadSignal, RwSignal, StoredValue,
};
use std::{future::Future, pin::Pin, rc::Rc};

Expand Down Expand Up @@ -210,33 +210,35 @@ where
tracing::instrument(level = "trace", skip_all,)
)]
pub fn dispatch(&self, input: I) {
let fut = (self.action_fn)(&input);
if !is_suppressing_resource_load() {
let fut = (self.action_fn)(&input);

let submission = Submission {
input: create_rw_signal(Some(input)),
value: create_rw_signal(None),
pending: create_rw_signal(true),
canceled: create_rw_signal(false),
};
let submission = Submission {
input: create_rw_signal(Some(input)),
value: create_rw_signal(None),
pending: create_rw_signal(true),
canceled: create_rw_signal(false),
};

self.submissions.update(|subs| subs.push(submission));
self.submissions.update(|subs| subs.push(submission));

let canceled = submission.canceled;
let input = submission.input;
let pending = submission.pending;
let value = submission.value;
let version = self.version;
let canceled = submission.canceled;
let input = submission.input;
let pending = submission.pending;
let value = submission.value;
let version = self.version;

spawn_local(async move {
let new_value = fut.await;
let canceled = untrack(move || canceled.get());
if !canceled {
value.set(Some(new_value));
}
input.set(None);
pending.set(false);
version.update(|n| *n += 1);
})
spawn_local(async move {
let new_value = fut.await;
let canceled = untrack(move || canceled.get());
if !canceled {
value.set(Some(new_value));
}
input.set(None);
pending.set(false);
version.update(|n| *n += 1);
})
}
}

/// The set of all submissions to this multi-action.
Expand Down

0 comments on commit d118496

Please sign in to comment.