[web-console] Add connector health UI to Performance tab#5801
[web-console] Add connector health UI to Performance tab#5801Karakatiza666 merged 4 commits intomainfrom
Conversation
mythical-fred
left a comment
There was a problem hiding this comment.
New connector health filter and unhealthy chip are useful additions, but this introduces untested behavior. See inline.
| if (unhealthyConnectors.length > 0) { | ||
| filtered.set(relation, { ...data, connectors: unhealthyConnectors }) | ||
| } | ||
| } |
There was a problem hiding this comment.
This introduces stateful filtering logic (healthFilter, filteredTables, filteredViews, unhealthyCount) with no tests. The hard rule for web-console: any behavior change needs tests.
numConnectorsWithProblems (systemErrors.ts) and the filtering logic here are pure functions -- easy to cover with Vitest + @testing-library/svelte. At minimum:
- isUnhealthy: does it correctly identify Unhealthy vs other statuses?
- filteredTables/filteredViews: does filtering by 'unhealthy' correctly exclude healthy connectors?
- numConnectorsWithProblems: does it count unhealthy connectors in addition to error counts?
| feldera_types::query::AdHocResultFormat, | ||
| feldera_types::format::json::JsonUpdateFormat, | ||
| feldera_types::format::json::JsonLines, | ||
| feldera_types::preprocess::PreprocessorConfig, |
There was a problem hiding this comment.
This seems unrelated to this PR.
There was a problem hiding this comment.
This change is required for a successful generation of OpenAPI bindings - the OpenAPI spec was referencing this new struct, but the struct itself was missing.
| export type AggregatedOutputEndpointMetrics = AggregatedMetrics< | ||
| OutputEndpointMetrics, | ||
| { io_active: boolean } | ||
| { io_active: boolean; health?: ConnectorHealth | null } |
There was a problem hiding this comment.
is the health optional because of backwards-compatibility?
In this case you could have a TODO to remove the null eventually.
There was a problem hiding this comment.
It is optional in the API, so reflected as such in TypeScript
| ) => void | ||
| } = $props() | ||
|
|
||
| type HealthFilter = 'all' | 'unhealthy' |
There was a problem hiding this comment.
From the images given as part of the PR I didn't guess that there is actually a selector between "all" and "unhealthy". I don't know if there's a better way to show this visually. A combo box would work, but wouldn't make it clear that there are only two choices. Maybe a slider with two positions and one label only (all/unhealthy)?
There was a problem hiding this comment.
I suspect we may have multiple different criteria we may want to filter connectors on; we have other instances of this selector UI component in the web-console: dark theme switch, selector on the Demos page, in the new Connector Errors list, and a few in mobile mode.
| return count | ||
| }) | ||
|
|
||
| const filteredTables = $derived.by(() => { |
There was a problem hiding this comment.
I would call this tablesFilteredByHealth
There was a problem hiding this comment.
Again, health status may be one of multiple things we may want to filter on in the future
| data.connectors | ||
| .filter(isUnhealthy) | ||
| .map((c) => c.health?.description) | ||
| .filter(Boolean) |
There was a problem hiding this comment.
what is .filter(Boolean)?
There was a problem hiding this comment.
It passes Boolean built-in function as a filter condition - it converts the argument value to bool based on JS's nullish-ness. In effect, this filters out empty descriptions.
There was a problem hiding this comment.
I didn't know that Boolean is a built-in function, I think writing it as a lambda would be clearer
There was a problem hiding this comment.
Well there are three candidates:
.filter(Boolean)- we covered that; and Boolean passed as a .filter() argument implies it has to be a function.filter(v => v)- explicit lambda, concise, and still has an implicit "nullish"-check - this is the built-in JS behavior of casting values to bool.filter(v => nonNull(v) && v !== "")- fully explicit, usesnonNullhelper; I can change the condition to this, but this just re-impements the nullish check.
I assume you prefer the option 3, but I would argue the intent should be expressed with the balance of conciseness and simplicity of used primitives.
So I will refactor to variant 3 here, and hope you'll find the pattern 1 reasonable in the future.
There was a problem hiding this comment.
how about a comment about what Boolean is?
There was a problem hiding this comment.
Rather, I'll document what Boolean filters out here:
// Filter out missing and empty descriptions to avoid large gaps in the combined text
I don't think it's meaningful to just document rather simple JS features
8b4086c to
8c108e5
Compare
|
Added unit tests for connector tables using vitest, @vitest/browser-playwright and vitest-browser-svelte |
mythical-fred
left a comment
There was a problem hiding this comment.
Tests landed. 659-line vitest-browser-svelte spec covers basic rendering, metric display, io_active indicator, all connector status icon states, multi-connector expand/collapse, error button callbacks, health chips, and the filter logic I flagged. CI runs it in a real Playwright container. LGTM.
34cd71c to
9bb7e2f
Compare
dad3a6f to
05b2b62
Compare
05b2b62 to
3c125cf
Compare
Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
3c125cf to
fc55ca1
Compare
Tested: manually


