-
Notifications
You must be signed in to change notification settings - Fork 8.8k
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
React UI: Add Starting Screen to Individual Pages #8909
Conversation
Signed-off-by: Levi Harrison <git@leviharrison.dev>
Hmmm, so now this is doing a request to prometheus/web/ui/react-app/src/App.tsx Line 68 in d44b4c5
prometheus/web/ui/react-app/src/App.tsx Line 72 in d44b4c5
StartingContext . Or maybe there's an even better way to solve it?
|
Ah, going from the initial comment I thought we wanted that behavior removed. I don't see any clear advantage between a global variable and a context, besides that a global might be simpler. Both could start off One other thing to consider is React not liking conditional hooks, which means that any time we include one of our |
Ah yeah, so I meant that each page should react to the current readiness state separately, but since we're a single-page app with multiple routes that can be navigated to without a full page reload, we can just load the readiness state once initially upon load of the SPA and then consume it from everywhere.
Yes, you always have to use the same hooks within one component, but the hooks can internally decide whether they need to do an actual HTTP fetch or not. So if we went for the global variable variant, I would put boolean |
Signed-off-by: Levi Harrison <git@leviharrison.dev>
OK, now a |
Signed-off-by: Levi Harrison <git@leviharrison.dev>
web/ui/react-app/src/utils/index.ts
Outdated
|
||
export const checkReady = (res: FetchStateReady): boolean => { | ||
const { ready, isLoading, isUnexpected } = res; | ||
if (!ready && !isLoading && !isUnexpected) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused by this string of AND conditions: So e.g. if it's not ready, but it's still loading, then we already return true
?
Intuitively I would have expected something closer to:
if (!ready && !isLoading && !isUnexpected) { | |
return ready && !isLoading && !isUnexpected; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that function could be simplified, but my logic here is that we can only determine that the server is on but not ready if:
- The variable we get indicates it's not ready
- We have stopped loading.
- The response is not an error.
If the response is an error, that means something is wrong with the server or it's not on, so we want to let those error messages show and return true
. We could probably change this to be showReadyScreen
, where we return true in the case that we can determine that we should show the ready screen, and false for everything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that would be more along my expectation - treat anything as not ready unless we positively get a working ready
message back from Prometheus. Otherwise, the startup indicator component should be responsible for saying "nope it's not ready yet" and either show the loading state or the readiness-loading error.
I tried adding |
Oh whoops, it doesn't. It then keeps reloading the whole page after everything is ready, so need to look a bit more. |
Ok, so the issue is that the continuous update to the readiness state is only maintained in the Actually I think it would even be best to put all that startup logic into the existing We already use |
So we'll continue to use the |
@LeviHarrison Yep, that's exactly what I was thinking! |
I just noticed though that |
So that would mean keeping a separate start-loader component after all, but then it would have to be wrapped around each page like this: Where previously you had:
...you could have:
And the |
Signed-off-by: Levi Harrison <git@leviharrison.dev>
web/ui/react-app/src/App.tsx
Outdated
@@ -64,6 +54,16 @@ const App: FC<AppProps> = ({ consolesLink }) => { | |||
theme = browserHasThemes ? (browserWantsDarkTheme ? 'dark' : 'light') : 'light'; | |||
} | |||
|
|||
const PanelListPage = withStartingIndicator(PanelList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. I like how all this stuff is now in one place an not in every component.
} | ||
if (res.status !== 503) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: doesn't this set isUnexpected
to true
whenever we get a 200
status code? Should it be an else if
and not just an if
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah probably.
setReady(true); | ||
} else { | ||
// This helps avoid a memory leak. | ||
let mounted = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain the leak a bit? As far as I can see, this is used to control whether the hook state setters are called on a mounted vs. unmounted component, but that shouldn't change anything with regards to actually leaking memory, it would just hide the memory leak warning, right? With the leak being in the form of the still-running fetchStatus()
. Would the proper way be to cancel the fetch()
request upon unmount? I found https://www.robinwieruch.de/react-warning-cant-call-setstate-on-an-unmounted-component which also presents your workaround, but AFAIU it's more of a warning suppressor than an actual memory leak preventor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I tried using an abort signal to cancel the request and the error still presented itself, although this may require further investigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, odd. Ok, let's keep it like this for now.
Signed-off-by: Levi Harrison <git@leviharrison.dev>
I think we're one small test failure away from being done:
|
Signed-off-by: Levi Harrison <git@leviharrison.dev>
Signed-off-by: Levi Harrison <git@leviharrison.dev>
Signed-off-by: Levi Harrison <git@leviharrison.dev>
Signed-off-by: Levi Harrison <git@leviharrison.dev>
I moved the |
Signed-off-by: Levi Harrison <git@leviharrison.dev>
Signed-off-by: Levi Harrison <git@leviharrison.dev>
I was locked in an endless cycle of eslint not wanting a trailing comma and prettier wanting one in |
const TargetsPage = withStartingIndicator(Targets); | ||
const PanelListPage = withStartingIndicator(PanelList); | ||
|
||
// prettier-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why's this needed vs. just letting prettier do its thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prettier wants a trailing comma, but when I add one, eslint errors saying there shouldn't be one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What the hell. That has never happened to me before, but I'm getting the same. Ok, let's look into that separately later, but that's weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not complaining about the trailing comma in the imports in App.tsx
, just the one here.
Now there's just another lint check failing:
|
Yep, working on it now. |
Signed-off-by: Levi Harrison <git@leviharrison.dev>
I got one more thing for the starting screen after this is merged, and then I think it's ready for release! |
Currently, when the starting screen finishes it redirects to the home page, even if you didn't start there. Also, because readiness is checked only on the site's initial load, navigating to other pages returns an error as before. This PR adds the starting screen to each individual page, and on completion, the page reloads (to re-fetch data), leaving the user on the view they requested. As it's no longer needed, I removed the
/starting
page.#8662 (comment)