Skip to content

Commit 4e123d4

Browse files
committed
concurrent fetch
1 parent b1c2fea commit 4e123d4

File tree

1 file changed

+178
-72
lines changed

1 file changed

+178
-72
lines changed

support/support.go

Lines changed: 178 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"net/http"
77
"strings"
8+
"sync"
89

910
"golang.org/x/xerrors"
1011

@@ -61,84 +62,141 @@ type Deps struct {
6162
}
6263

6364
func DeploymentInfo(ctx context.Context, client *codersdk.Client, log slog.Logger) Deployment {
64-
var d Deployment
65-
66-
bi, err := client.BuildInfo(ctx)
67-
if err != nil {
68-
log.Error(ctx, "fetch build info", slog.Error(err))
69-
} else {
65+
var (
66+
d Deployment
67+
m sync.Mutex
68+
wg sync.WaitGroup
69+
)
70+
71+
wg.Add(1)
72+
go func() {
73+
defer wg.Done()
74+
bi, err := client.BuildInfo(ctx)
75+
if err != nil {
76+
log.Error(ctx, "fetch build info", slog.Error(err))
77+
return
78+
}
79+
m.Lock()
7080
d.BuildInfo = &bi
71-
}
81+
m.Unlock()
82+
}()
7283

73-
dc, err := client.DeploymentConfig(ctx)
74-
if err != nil {
75-
log.Error(ctx, "fetch deployment config", slog.Error(err))
76-
} else {
84+
wg.Add(1)
85+
go func() {
86+
defer wg.Done()
87+
dc, err := client.DeploymentConfig(ctx)
88+
if err != nil {
89+
log.Error(ctx, "fetch deployment config", slog.Error(err))
90+
return
91+
}
92+
m.Lock()
7793
d.Config = dc
78-
}
94+
m.Unlock()
95+
}()
7996

80-
hr, err := client.DebugHealth(ctx)
81-
if err != nil {
82-
log.Error(ctx, "fetch health report", slog.Error(err))
83-
} else {
97+
wg.Add(1)
98+
go func() {
99+
defer wg.Done()
100+
hr, err := client.DebugHealth(ctx)
101+
if err != nil {
102+
log.Error(ctx, "fetch health report", slog.Error(err))
103+
return
104+
}
105+
m.Lock()
84106
d.HealthReport = &hr
85-
}
107+
m.Unlock()
108+
}()
86109

87-
exp, err := client.Experiments(ctx)
88-
if err != nil {
89-
log.Error(ctx, "fetch experiments", slog.Error(err))
90-
} else {
110+
wg.Add(1)
111+
go func() {
112+
defer wg.Done()
113+
exp, err := client.Experiments(ctx)
114+
if err != nil {
115+
log.Error(ctx, "fetch experiments", slog.Error(err))
116+
return
117+
}
118+
m.Lock()
91119
d.Experiments = exp
92-
}
120+
m.Unlock()
121+
}()
93122

123+
wg.Wait()
94124
return d
95125
}
96126

97127
func NetworkInfo(ctx context.Context, client *codersdk.Client, log slog.Logger, agentID uuid.UUID) Network {
98-
var n Network
99-
100-
coordResp, err := client.Request(ctx, http.MethodGet, "/api/v2/debug/coordinator", nil)
101-
if err != nil {
102-
log.Error(ctx, "fetch coordinator debug page", slog.Error(err))
103-
} else {
128+
var (
129+
n Network
130+
m sync.Mutex
131+
wg sync.WaitGroup
132+
)
133+
134+
wg.Add(1)
135+
go func() {
136+
defer wg.Done()
137+
coordResp, err := client.Request(ctx, http.MethodGet, "/api/v2/debug/coordinator", nil)
138+
if err != nil {
139+
log.Error(ctx, "fetch coordinator debug page", slog.Error(err))
140+
return
141+
}
104142
defer coordResp.Body.Close()
105143
bs, err := io.ReadAll(coordResp.Body)
106144
if err != nil {
107145
log.Error(ctx, "read coordinator debug page", slog.Error(err))
108-
} else {
109-
n.CoordinatorDebug = string(bs)
146+
return
110147
}
111-
}
148+
m.Lock()
149+
n.CoordinatorDebug = string(bs)
150+
m.Unlock()
151+
}()
112152

113-
tailResp, err := client.Request(ctx, http.MethodGet, "/api/v2/debug/tailnet", nil)
114-
if err != nil {
115-
log.Error(ctx, "fetch tailnet debug page", slog.Error(err))
116-
} else {
153+
wg.Add(1)
154+
go func() {
155+
defer wg.Done()
156+
tailResp, err := client.Request(ctx, http.MethodGet, "/api/v2/debug/tailnet", nil)
157+
if err != nil {
158+
log.Error(ctx, "fetch tailnet debug page", slog.Error(err))
159+
return
160+
}
117161
defer tailResp.Body.Close()
118162
bs, err := io.ReadAll(tailResp.Body)
119163
if err != nil {
120164
log.Error(ctx, "read tailnet debug page", slog.Error(err))
121-
} else {
122-
n.TailnetDebug = string(bs)
165+
return
123166
}
124-
}
167+
m.Lock()
168+
n.TailnetDebug = string(bs)
169+
m.Unlock()
170+
}()
125171

126-
if agentID != uuid.Nil {
172+
wg.Add(1)
173+
go func() {
174+
defer wg.Done()
175+
if agentID == uuid.Nil {
176+
log.Warn(ctx, "agent id required for agent connection info")
177+
return
178+
}
127179
connInfo, err := client.WorkspaceAgentConnectionInfo(ctx, agentID)
128180
if err != nil {
129181
log.Error(ctx, "fetch agent conn info", slog.Error(err), slog.F("agent_id", agentID.String()))
130-
} else {
131-
n.NetcheckLocal = &connInfo
182+
return
132183
}
133-
} else {
134-
log.Warn(ctx, "agent id required for agent connection info")
135-
}
184+
m.Lock()
185+
n.NetcheckLocal = &connInfo
186+
m.Unlock()
187+
}()
188+
189+
wg.Wait()
136190

137191
return n
138192
}
139193

140194
func WorkspaceInfo(ctx context.Context, client *codersdk.Client, log slog.Logger, workspaceID, agentID uuid.UUID) Workspace {
141-
var w Workspace
195+
var (
196+
w Workspace
197+
m sync.Mutex
198+
wg sync.WaitGroup
199+
)
142200

143201
if workspaceID == uuid.Nil {
144202
log.Error(ctx, "no workspace id specified")
@@ -149,44 +207,66 @@ func WorkspaceInfo(ctx context.Context, client *codersdk.Client, log slog.Logger
149207
log.Error(ctx, "no agent id specified")
150208
}
151209

210+
// dependency, cannot fetch concurrently
152211
ws, err := client.Workspace(ctx, workspaceID)
153212
if err != nil {
154213
log.Error(ctx, "fetch workspace", slog.Error(err), slog.F("workspace_id", workspaceID))
155214
return w
156215
}
157-
158-
agt, err := client.WorkspaceAgent(ctx, agentID)
159-
if err != nil {
160-
log.Error(ctx, "fetch workspace agent", slog.Error(err), slog.F("agent_id", agentID))
161-
}
162-
163216
w.Workspace = ws
164-
w.Agent = agt
165217

166-
buildLogCh, closer, err := client.WorkspaceBuildLogsAfter(ctx, ws.LatestBuild.ID, 0)
167-
if err != nil {
168-
log.Error(ctx, "fetch provisioner job logs", slog.Error(err), slog.F("job_id", ws.LatestBuild.Job.ID.String()))
169-
} else {
218+
wg.Add(1)
219+
go func() {
220+
defer wg.Done()
221+
agt, err := client.WorkspaceAgent(ctx, agentID)
222+
if err != nil {
223+
log.Error(ctx, "fetch workspace agent", slog.Error(err), slog.F("agent_id", agentID))
224+
}
225+
m.Lock()
226+
w.Agent = agt
227+
m.Unlock()
228+
}()
229+
230+
wg.Add(1)
231+
go func() {
232+
defer wg.Done()
233+
buildLogCh, closer, err := client.WorkspaceBuildLogsAfter(ctx, ws.LatestBuild.ID, 0)
234+
if err != nil {
235+
log.Error(ctx, "fetch provisioner job logs", slog.Error(err), slog.F("job_id", ws.LatestBuild.Job.ID.String()))
236+
return
237+
}
170238
defer closer.Close()
239+
var logs []codersdk.ProvisionerJobLog
171240
for log := range buildLogCh {
172-
w.BuildLogs = append(w.BuildLogs, log)
241+
logs = append(w.BuildLogs, log)
173242
}
174-
}
175-
176-
if len(w.Workspace.LatestBuild.Resources) == 0 {
177-
log.Warn(ctx, "workspace build has no resources")
178-
return w
179-
}
243+
m.Lock()
244+
w.BuildLogs = logs
245+
m.Unlock()
246+
}()
180247

181-
agentLogCh, closer, err := client.WorkspaceAgentLogsAfter(ctx, agentID, 0, false)
182-
if err != nil {
183-
log.Error(ctx, "fetch agent startup logs", slog.Error(err), slog.F("agent_id", agentID.String()))
184-
} else {
248+
wg.Add(1)
249+
go func() {
250+
defer wg.Done()
251+
if len(w.Workspace.LatestBuild.Resources) == 0 {
252+
log.Warn(ctx, "workspace build has no resources")
253+
return
254+
}
255+
agentLogCh, closer, err := client.WorkspaceAgentLogsAfter(ctx, agentID, 0, false)
256+
if err != nil {
257+
log.Error(ctx, "fetch agent startup logs", slog.Error(err), slog.F("agent_id", agentID.String()))
258+
}
185259
defer closer.Close()
260+
var logs []codersdk.WorkspaceAgentLog
186261
for logChunk := range agentLogCh {
187-
w.AgentStartupLogs = append(w.AgentStartupLogs, logChunk...)
262+
logs = append(w.AgentStartupLogs, logChunk...)
188263
}
189-
}
264+
m.Lock()
265+
w.AgentStartupLogs = logs
266+
m.Unlock()
267+
}()
268+
269+
wg.Wait()
190270

191271
return w
192272
}
@@ -225,9 +305,35 @@ func Run(ctx context.Context, d *Deps) (*Bundle, error) {
225305
}
226306
}
227307

228-
b.Deployment = DeploymentInfo(ctx, d.Client, d.Log)
229-
b.Workspace = WorkspaceInfo(ctx, d.Client, d.Log, d.WorkspaceID, d.AgentID)
230-
b.Network = NetworkInfo(ctx, d.Client, d.Log, d.AgentID)
308+
var (
309+
wg sync.WaitGroup
310+
m sync.Mutex
311+
)
312+
wg.Add(1)
313+
go func() {
314+
defer wg.Done()
315+
di := DeploymentInfo(ctx, d.Client, d.Log)
316+
m.Lock()
317+
b.Deployment = di
318+
m.Unlock()
319+
}()
320+
wg.Add(1)
321+
go func() {
322+
defer wg.Done()
323+
wi := WorkspaceInfo(ctx, d.Client, d.Log, d.WorkspaceID, d.AgentID)
324+
m.Lock()
325+
b.Workspace = wi
326+
m.Unlock()
327+
}()
328+
wg.Add(1)
329+
go func() {
330+
defer wg.Done()
331+
ni := NetworkInfo(ctx, d.Client, d.Log, d.AgentID)
332+
m.Lock()
333+
b.Network = ni
334+
m.Unlock()
335+
}()
336+
wg.Wait()
231337

232338
return &b, nil
233339
}

0 commit comments

Comments
 (0)