-
Notifications
You must be signed in to change notification settings - Fork 887
feat(site): add agent connection timings #15276
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
Conversation
@dannykopping I would appreciate a first round of review in the BE code and its usage. |
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.
Overall looking good!
Added a few notes for things we can do to harden.
coderd/workspacebuilds_test.go
Outdated
require.Empty(t, res.AgentScriptTimings) | ||
}) | ||
|
||
//nolint:paralleltest |
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.
Howcome these are not in parallel?
All mentions of nolint
should be followed with a reason like:
//nolint:paralleltest // Reason.
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 just following what we are already doing in other places:
coder/coderd/workspacebuilds_test.go
Line 1186 in 3e1170c
//nolint:paralleltest coder/coderd/workspacebuilds_test.go
Line 1240 in 3e1170c
//nolint:paralleltest coder/coderd/workspacebuilds_test.go
Line 1255 in 3e1170c
//nolint:paralleltest
All of them have the same reason based on this PR even thinking I had fixed it here.
coderd/workspacebuilds.go
Outdated
StartedAt: agent.CreatedAt, | ||
Stage: "connect", | ||
EndedAt: agent.FirstConnectedAt.Time, |
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.
first_connected_at
is a nullable field; what do we do in this case?
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 not sure. In this case, we should not return or display the connection stage in the chart 🤔 wdyt?
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.
Can we show some pending state in this case?
Co-authored-by: Danny Kopping <danny@coder.com>
.vscode/settings.json
Outdated
}, | ||
"[typescriptreact]": { | ||
"editor.defaultFormatter": "biomejs.biome" |
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.
look a couple lines above, we already set this
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 don't know why my vscode didn't recognize that
key={stage.name} | ||
id={encodeURIComponent(stage.name)} | ||
> | ||
{stages.map((s) => ( |
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.
nit: I liked stage
as a variable name here more. single letter variables names make me sad. :(
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 working too much with Go lately 😆
const stages = () => { | ||
const agentStageLabels = Array.from( | ||
new Set( | ||
agentConnectionTimings.map((t) => `agent (${t.workspace_agent_name})`), | ||
), | ||
); | ||
return [ | ||
...provisioningStages, | ||
...agentStageLabels.flatMap((a) => agentStages(a)), | ||
]; | ||
}; | ||
|
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 put this in a function that doesn't take any arguments and is only called once? if it's a performance concern, we should probably be using useMemo
instead
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.
That is true. I tried to improve readability by grouping related code to a function.
@@ -135,19 +158,18 @@ export const WorkspaceTimings: FC<WorkspaceTimingsProps> = ({ | |||
)} | |||
|
|||
{view.name === "detailed" && | |||
view.category.id === "workspaceBoot" && ( | |||
view.stage.section !== "provisioning" && ( |
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.
this could be put in a ternary with the condition above to reduce repeated conditions
.map((t) => { | ||
return { | ||
range: extractRange(t), | ||
range: toTimeRange(t), | ||
name: t.display_name, | ||
status: t.status, | ||
exitCode: t.exit_code, | ||
}; | ||
})} |
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 be an implicit return
.map((t) => { | |
return { | |
range: extractRange(t), | |
range: toTimeRange(t), | |
name: t.display_name, | |
status: t.status, | |
exitCode: t.exit_code, | |
}; | |
})} | |
.map((t) => ({ | |
range: toTimeRange(t), | |
name: t.display_name, | |
status: t.status, | |
exitCode: t.exit_code, | |
})) |
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.
LGTM, a few minor nits & notes but I'm happy!
coderd/workspacebuilds.go
Outdated
WorkspaceAgentID: agent.ID.String(), | ||
WorkspaceAgentName: agent.Name, | ||
StartedAt: agent.CreatedAt, | ||
Stage: "connect", |
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 we should add constants for these stages, and share them across coderd & the frontend.
@@ -1264,19 +1271,21 @@ func TestWorkspaceBuildTimings(t *testing.T) { | |||
require.Empty(t, res.AgentScriptTimings) | |||
}) | |||
|
|||
//nolint:paralleltest |
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 were these marked as not parallel before? I'm concerned we're rolling back a change which was necessary to avoid some previous issue.
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 was a conflict with the following PRs:
resource := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{ | ||
JobID: build.JobID, | ||
}) | ||
agents := make([]database.WorkspaceAgent, 5) |
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.
Reminder about this one
<TooltipShortDescription> | ||
Time taken to establish an RPC connection with the control plane. | ||
</TooltipShortDescription> | ||
</> | ||
), | ||
}, | ||
}, | ||
{ | ||
name: "start", | ||
label: "run startup scripts", | ||
section, | ||
tooltip: { | ||
title: ( | ||
<> | ||
<TooltipTitle>Run startup scripts</TooltipTitle> | ||
<TooltipShortDescription> | ||
Time taken to run each agent startup script. | ||
</TooltipShortDescription> |
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 wonder if we should drop the "time taken" on these stages since the other sections' stages don't have them.
<TooltipShortDescription> | |
Time taken to establish an RPC connection with the control plane. | |
</TooltipShortDescription> | |
</> | |
), | |
}, | |
}, | |
{ | |
name: "start", | |
label: "run startup scripts", | |
section, | |
tooltip: { | |
title: ( | |
<> | |
<TooltipTitle>Run startup scripts</TooltipTitle> | |
<TooltipShortDescription> | |
Time taken to run each agent startup script. | |
</TooltipShortDescription> | |
<TooltipShortDescription> | |
Establish an RPC connection with the control plane. | |
</TooltipShortDescription> | |
</> | |
), | |
}, | |
}, | |
{ | |
name: "start", | |
label: "run startup scripts", | |
section, | |
tooltip: { | |
title: ( | |
<> | |
<TooltipTitle>Run startup scripts</TooltipTitle> | |
<TooltipShortDescription> | |
Execute each agent startup script. | |
</TooltipShortDescription> |
@@ -11,6 +11,7 @@ const meta: Meta<typeof WorkspaceTimings> = { | |||
defaultIsOpen: true, | |||
provisionerTimings: WorkspaceTimingsResponse.provisioner_timings, | |||
agentScriptTimings: WorkspaceTimingsResponse.agent_script_timings, | |||
agentConnectionTimings: WorkspaceTimingsResponse.agent_connection_timings, |
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.
Do we need some frontend tests for these timings?
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.
Not specifically, if you see the stories, they are already represented there. If the component does not display for any reason, Chromatic will issue a warning.
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.
LGTM 👍
Local preview:
Close coder/internal#116