Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify/clarify client loading for all templates #442

Open
pdaoust opened this issue Jan 2, 2025 · 8 comments
Open

Simplify/clarify client loading for all templates #442

pdaoust opened this issue Jan 2, 2025 · 8 comments

Comments

@pdaoust
Copy link
Collaborator

pdaoust commented Jan 2, 2025

In #424 we described the discovery that Svelte templates will fail with an error message when you load a component before the HC client is loaded. #425 fixed it by adding an async getClient function and having the children await on that function.

In #436 I said the race condition is also present in Vue templates. @c12i suggested I just put the child components inside the root component's "if loading" guard, which seems to me to be a much more elegant solution than making the children responsible for awaiting client state.

If others (cc @c12i @matthme @mattyg ) think this is a better way to go, then we need two follow-up tasks:

  1. Revert Fix race condition in Svelte template #425
  2. Update the getting started guide with correct code
  3. (optional) In all templates, make a note about where to put child components so they're loaded when the client is ready.
@pdaoust pdaoust added this to Holochain Jan 2, 2025
@github-project-automation github-project-automation bot moved this to Backlog in Holochain Jan 2, 2025
@matthme
Copy link
Collaborator

matthme commented Jan 2, 2025

To clarify, the getClient() function was already there before in the Svelte template, it was just not safe against the client not having been loaded at that point as it was synchronous, now it's async.

@matthme
Copy link
Collaborator

matthme commented Jan 2, 2025

I'm not convinced yet that this is overall more elegant. Many components typically need to keep track of a loading state anyway, for example to make a zome call to fetch all posts to display. So we might not really be able to get rid of having loading states in the components with this change. And if the error occurs anyway due to a component being accidentally or due to lack of understanding placed outside an if block it is not trivial to find the reason for the error...

@matthme
Copy link
Collaborator

matthme commented Jan 2, 2025

Maybe what I'd say is that it's reasonable to do it that way in Vue but I think it's probably not worth reverting the changes in the Svelte template if there often is async stuff to be done in the onMount hook of components anyway.

@pdaoust
Copy link
Collaborator Author

pdaoust commented Jan 2, 2025

Child components do have their own loading state for loading the component's data via zome call, that's true. And they don't really have to handle an extra on-loading state as the client is being connected, and the changes are pretty small for a decent benefit to the hApp dev, I suppose.

(NB looks like #425 merely moved the getClient function around, you're right. Re: Svelte vs Vue, AFAICT they're pretty much equivalent in terms of component mounting and hence show the same race condition, so whatever we do for one would be lovely to do for both -- whichever way we decide.)

@c12i
Copy link
Collaborator

c12i commented Jan 3, 2025

Many components typically need to keep track of a loading state anyway, for example to make a zome call to fetch all posts to display

This is true, although there are two loading states in this case, one for fetching data as you described and the other for setting up the initial websocket connection, I think the child components would need to be able to get some sort of isClientReady state and also a ws connection error state so that this can be handled gracefully at the component level or at the parent level as I had suggested to @pdaoust

@mattyg
Copy link
Member

mattyg commented Jan 3, 2025

I'm not sure I'm understanding the question here, but my approach is always to make sure the holochain client is connected before rendering any app content. While awaiting connection to the holochain client I display a general loading screen.

To me this is simple and ideal because it avoids pushing down the logic for checking if the client is connected into all the components, and only does it in one place. The components always have a connected client and the dev doesn't ever have to think about it.

@pdaoust
Copy link
Collaborator Author

pdaoust commented Jan 3, 2025

@mattyg yes, that's what I'm advocating -- don't put too much responsibility on child components, let it break if you mount them in the wrong spot, and give hApp devs some guideposts to help them understand this behaviour. Should be graspable cuz it's not that different from establishing any WebSocket connection -- you want to await the promise before you do anything that requires the conn.

@c12i
Copy link
Collaborator

c12i commented Jan 7, 2025

Exactly, I would prefer to keep it simple like that and have that guard/ check much higher up the tree.

The approach that was implemented with #425 while it still works, still doesn't guarantee safety, especially when the call to AppWebSocket.connect unexpectedly fails here https://github.com/holochain/scaffolding/pull/425/files#diff-26fe7f87557da92c4e315ef629b4093ef32e661ce7e41e01c3845b782ca17dddR13. Perhaps some error handling would have been useful in that case, what do you think @matthme?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

No branches or pull requests

4 participants