Skip to content

Commit ebfc133

Browse files
fix: display build timings when all timings are loaded (#15728)
- [Refetch timings until script timings are present](2181bec) - [Stay on loading state when agent script timings are empty](b16fad1) Fix #15273
1 parent c7c35ef commit ebfc133

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

site/src/api/queries/workspaceBuilds.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,9 @@ export const infiniteWorkspaceBuilds = (
5858
};
5959

6060
// We use readyAgentsCount to invalidate the query when an agent connects
61-
export const workspaceBuildTimings = (
62-
workspaceBuildId: string,
63-
readyAgentsCount: number,
64-
) => {
61+
export const workspaceBuildTimings = (workspaceBuildId: string) => {
6562
return {
66-
queryKey: [
67-
"workspaceBuilds",
68-
workspaceBuildId,
69-
"timings",
70-
{ readyAgentsCount },
71-
],
63+
queryKey: ["workspaceBuilds", workspaceBuildId, "timings"],
7264
queryFn: () => API.workspaceBuildTimings(workspaceBuildId),
7365
};
7466
};

site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,11 @@ export const DuplicatedScriptTiming: Story = {
118118
],
119119
},
120120
};
121+
122+
// Loading when agent script timings are empty
123+
// Test case for https://github.com/coder/coder/issues/15273
124+
export const LoadingWhenAgentScriptTimingsAreEmpty: Story = {
125+
args: {
126+
agentScriptTimings: undefined,
127+
},
128+
};

site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,25 @@ export const WorkspaceTimings: FC<WorkspaceTimingsProps> = ({
5858
].sort((a, b) => {
5959
return new Date(a.started_at).getTime() - new Date(b.started_at).getTime();
6060
});
61+
6162
const [isOpen, setIsOpen] = useState(defaultIsOpen);
62-
const isLoading = timings.length === 0;
6363

64-
// All stages
64+
// If any of the timings are empty, we are still loading the data. They can be
65+
// filled in different moments.
66+
const isLoading = [
67+
provisionerTimings,
68+
agentScriptTimings,
69+
agentConnectionTimings,
70+
].some((t) => t.length === 0);
71+
72+
// Each agent connection timing is a stage in the timeline to make it easier
73+
// to users to see the timing for connection and the other scripts.
6574
const agentStageLabels = Array.from(
6675
new Set(
6776
agentConnectionTimings.map((t) => `agent (${t.workspace_agent_name})`),
6877
),
6978
);
79+
7080
const stages = [
7181
...provisioningStages,
7282
...agentStageLabels.flatMap((a) => agentStages(a)),
@@ -120,7 +130,8 @@ export const WorkspaceTimings: FC<WorkspaceTimingsProps> = ({
120130
: mergeTimeRanges(stageTimings.map(toTimeRange));
121131

122132
// Prevent users from inspecting internal coder resources in
123-
// provisioner timings.
133+
// provisioner timings because they were not useful to the
134+
// user and would add noise.
124135
const visibleResources = stageTimings.filter((t) => {
125136
const isProvisionerTiming = "resource" in t;
126137
return isProvisionerTiming

site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,27 @@ export const WorkspaceReadyPage: FC<WorkspaceReadyPageProps> = ({
157157
// Cancel build
158158
const cancelBuildMutation = useMutation(cancelBuild(workspace, queryClient));
159159

160-
// Build Timings. Fetch build timings only when the build job is completed.
161-
const readyAgents = workspace.latest_build.resources
162-
.flatMap((r) => r.agents)
163-
.filter((a) => a && a.lifecycle_state !== "starting");
160+
// Workspace Timings.
164161
const timingsQuery = useQuery({
165-
...workspaceBuildTimings(workspace.latest_build.id, readyAgents.length),
162+
...workspaceBuildTimings(workspace.latest_build.id),
163+
164+
// Fetch build timings only when the build job is completed.
166165
enabled: Boolean(workspace.latest_build.job.completed_at),
166+
167+
// Sometimes, the timings can be fetched before the agent script timings are
168+
// done or saved in the database so we need to conditionally refetch the
169+
// timings. To refetch the timings, I found the best way was to compare the
170+
// expected amount of script timings with the current amount of script
171+
// timings returned in the response.
172+
refetchInterval: (data) => {
173+
const expectedScriptTimingsCount = workspace.latest_build.resources
174+
.flatMap((r) => r.agents)
175+
.flatMap((a) => a?.scripts ?? []).length;
176+
const currentScriptTimingsCount = data?.agent_script_timings?.length ?? 0;
177+
return expectedScriptTimingsCount === currentScriptTimingsCount
178+
? false
179+
: 1_000;
180+
},
167181
});
168182

169183
const runLastBuild = (

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy