mirror of
https://github.com/gethomepage/homepage.git
synced 2026-09-28 06:51:17 -07:00
Performance: fetch all docker container statuses in one request (#7092)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
@@ -11,14 +11,16 @@ export default function Component({ service }) {
|
||||
|
||||
const { widget } = service;
|
||||
|
||||
const { data: statusData, error: statusError } = useSWR(
|
||||
`/api/docker/status/${widget.container}/${widget.server || ""}`,
|
||||
const { data: statusResponse, error: statusError } = useSWR(
|
||||
`/api/docker/statuses?server=${encodeURIComponent(widget.server || "")}`,
|
||||
);
|
||||
const { statuses } = statusResponse ?? {};
|
||||
const statusData = statuses ? (statuses[widget.container] ?? { status: "not found" }) : undefined;
|
||||
|
||||
const { data: statsData, error: statsError } = useSWR(`/api/docker/stats/${widget.container}/${widget.server || ""}`);
|
||||
|
||||
if (statsError || statsData?.error || statusError || statusData?.error) {
|
||||
const finalError = statsError ?? statsData?.error ?? statusError ?? statusData?.error;
|
||||
if (statsError || statsData?.error || statusError || statusResponse?.error) {
|
||||
const finalError = statsError ?? statsData?.error ?? statusError ?? statusResponse?.error;
|
||||
return <Container service={service} error={finalError} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ describe("widgets/docker/component", () => {
|
||||
|
||||
it("renders offline status when container is not running", () => {
|
||||
useSWR
|
||||
.mockReturnValueOnce({ data: { status: "exited" }, error: undefined }) // status
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined }); // stats
|
||||
.mockReturnValueOnce({ data: { statuses: { c: { status: "exited" } } }, error: undefined })
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "docker", container: "c" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
@@ -31,9 +31,34 @@ describe("widgets/docker/component", () => {
|
||||
expect(screen.getByText("docker.offline")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("surfaces a docker error payload instead of reporting the container offline", () => {
|
||||
useSWR
|
||||
.mockReturnValueOnce({ data: { error: { message: "socket unreachable" } }, error: undefined })
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "docker", container: "c", server: "s" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(screen.queryByText("docker.offline")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("treats a missing container in the bulk status map as offline", () => {
|
||||
useSWR
|
||||
.mockReturnValueOnce({ data: { statuses: {} }, error: undefined })
|
||||
.mockReturnValueOnce({ data: undefined, error: undefined });
|
||||
|
||||
renderWithProviders(<Component service={{ widget: { type: "docker", container: "c", server: "s" } }} />, {
|
||||
settings: { hideErrors: false },
|
||||
});
|
||||
|
||||
expect(useSWR).toHaveBeenCalledWith("/api/docker/statuses?server=s");
|
||||
expect(screen.getByText("docker.offline")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders cpu/mem/rx/tx values when stats are available", () => {
|
||||
useSWR
|
||||
.mockReturnValueOnce({ data: { status: "running" }, error: undefined }) // status
|
||||
.mockReturnValueOnce({ data: { statuses: { c: { status: "running" } } }, error: undefined })
|
||||
.mockReturnValueOnce({
|
||||
data: {
|
||||
stats: {
|
||||
|
||||
Reference in New Issue
Block a user