Should Actions 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
Uh oh!
There was an error while loading. Please reload this page.
-
Currently an
Actionbroadly combines these three functionalities:.pendingand.inputThis similarly applies to
MultiActions, 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_sqliteas an example. We have a list ofTodos 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 usingActions (broadly speaking, actuallyServerActionandServerMultiActionare 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 theResourcetodostodelete_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_todosto 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_todoanddelete_todoto 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
Actions 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 themEventActionfor 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.valueand instead every time the action completes, the passedprocess_resultis called with a reference to the input to the completed submission and the output.For plain
Actions this might not be entirely useful, since we could just merge the logic fromprocess_resultintoaction_fn's returned future, but the benefit becomes more clear forEventServerActionwhere the server function would take the place ofaction_fnbut we would still provideprocess_resultupon construction, so the server function would run on the server side, whileprocess_resultwould run on the client side.This concept can similarly be extended to
EventMultiActions, with the semantics ofprocess_resultbeing the same and the only difference being that entries in.submissionsdon't provide access to.value.I'm not entirely confident, but I think that the current behavior
ActionandMultiActioncould be implemented in terms ofEventActionandEventMultiAction, since all you'd have to do is to create a signal for the result and provide aprocess_resultthat 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_sqliteexample 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, andMultiServerActionthis would addEventAction,EventMultiAction,EventServerActionandEventMultiServerAction.Beta Was this translation helpful? Give feedback.
All reactions