Should Action
s be generalized to pass their output to a callback instead of putting it into a signal
#3251
Kritzefitz
started this conversation in
Ideas
Replies: 1 comment 1 reply
-
It is completely fine to create a different primitive that does this; I have no interest in making breaking changes to Action itself. I'm also not really interested in multiplying the number of different combinations that exist in the library itself in the way described, as I ultimately end up maintaining everything that gets added over time. I'm pretty sure this can be implemented in userland or as a library, although I may be wrong. Whether the "invalidate with an action and reload with a resource" pattern is good or not is kind of an orthogonal question. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Currently an
Action
broadly combines these three functionalities:.pending
and.input
This similarly applies to
MultiAction
s, which allow to track multiple in-flight actions, but each submission of the action still tracks if the action is still running and stores the output in a signal once available.It seems to me, like storing the output of the action in a signal is unnecessarily inflexible for at least some use cases.
Let's take the
todo_app_sqlite
as an example. We have a list ofTodo
s that are loaded on the client side and we allow the user to add to this list and to delete items from the list. These changes to the list are synchronized to the server usingAction
s (broadly speaking, actuallyServerAction
andServerMultiAction
are used, but the difference shouldn't matter for my example). Once an action to change the list has completed, the displayed list needs to be updated to reflect the changes. In the current example, this is achieved by subscribing theResource
todos
todelete_todo.version()
andadd_todo.version()
, which triggers a reload of the todos whenever they are changed. This achieves the intended result of updating the displayed list on changes, but it seems unnecessarily inefficient to reload the entire list of todos when we've actually done a very simple change to it. We rely on the server to calculate the new list of todos for us, causing a lot of transfer overhead, when we could relatively simply calculate the effect of our change to the list relatively easily on the client side. If we modifyget_todos
to return aRwResult<Vec<Todos>>
we gain the ability to modify the list of todos on the client side after retrieving it, but we'd still need to arrange for completions ofadd_todo
anddelete_todo
to be synchronized into thetodos
.This sounds easy enough on the surface, but it would actually be a little more complicated to implement, because we only gain access to the result of an action through a signal and AFAIK there's no way to sync changes in one signal to another signal, without a trip through an effect, which is generally frowned upon. So in this case, the fact that an action wraps its output in a signal seems to be less of a feature, but more of a hindrance.
I think it would be easier to model interactions like this, if we had variants of
Action
s that don't automatically store their output in a signal, but instead just receive a callback to call on each completion. For lack of a better name, I'll call themEventAction
for now and they would probably look somewhat like this:The rest of the interface would be very similar to
Action
, the only difference being that there's no.value
and instead every time the action completes, the passedprocess_result
is called with a reference to the input to the completed submission and the output.For plain
Action
s this might not be entirely useful, since we could just merge the logic fromprocess_result
intoaction_fn
's returned future, but the benefit becomes more clear forEventServerAction
where the server function would take the place ofaction_fn
but we would still provideprocess_result
upon construction, so the server function would run on the server side, whileprocess_result
would run on the client side.This concept can similarly be extended to
EventMultiAction
s, with the semantics ofprocess_result
being the same and the only difference being that entries in.submissions
don't provide access to.value
.I'm not entirely confident, but I think that the current behavior
Action
andMultiAction
could be implemented in terms ofEventAction
andEventMultiAction
, since all you'd have to do is to create a signal for the result and provide aprocess_result
that updates the signal appropriately.I'd be willing to take a stab at implementing this, but before I do, I wanted to ask if this seems like a useful idea. Does this solve an actual problem or is there an easier solution to the problem in the
todo_app_sqlite
example I described? Does anyone have a suggestion for a good name to differentiate these callback-based actions from traditional actions? Are the benefits worth the complexity of doubling the variants of actions we have? Since where we have nowAction
,MultiAction
,ServerAction
, andMultiServerAction
this would addEventAction
,EventMultiAction
,EventServerAction
andEventMultiServerAction
.Beta Was this translation helpful? Give feedback.
All reactions