@@ -3,7 +3,6 @@ package reports
3
3
import (
4
4
"context"
5
5
"database/sql"
6
- "fmt"
7
6
"io"
8
7
"slices"
9
8
"sort"
@@ -37,6 +36,7 @@ func NewReportGenerator(ctx context.Context, logger slog.Logger, db database.Sto
37
36
38
37
// Start the ticker with the initial delay.
39
38
ticker := clk .NewTicker (delay )
39
+ ticker .Stop ()
40
40
doTick := func (start time.Time ) {
41
41
defer ticker .Reset (delay )
42
42
// Start a transaction to grab advisory lock, we don't want to run generator jobs at the same time (multiple replicas).
@@ -98,11 +98,14 @@ func (i *reportGenerator) Close() error {
98
98
return nil
99
99
}
100
100
101
- const failedWorkspaceBuildsReportFrequencyDays = 7
101
+ const (
102
+ failedWorkspaceBuildsReportFrequency = 7 * 24 * time .Hour
103
+ failedWorkspaceBuildsReportFrequencyLabel = "week"
104
+ )
102
105
103
106
func reportFailedWorkspaceBuilds (ctx context.Context , logger slog.Logger , db database.Store , enqueuer notifications.Enqueuer , clk quartz.Clock ) error {
104
107
now := clk .Now ()
105
- since := now .Add (- failedWorkspaceBuildsReportFrequencyDays * 24 * time . Hour )
108
+ since := now .Add (- failedWorkspaceBuildsReportFrequency )
106
109
107
110
statsRows , err := db .GetWorkspaceBuildStatsByTemplates (ctx , dbtime .Time (since ).UTC ())
108
111
if err != nil {
@@ -128,7 +131,7 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
128
131
}
129
132
130
133
// There are some failed builds, so we have to prepare input data for the report.
131
- reportData = buildDataForReportFailedWorkspaceBuilds (failedWorkspaceBuildsReportFrequencyDays , stats , failedBuilds )
134
+ reportData = buildDataForReportFailedWorkspaceBuilds (stats , failedBuilds )
132
135
}
133
136
134
137
templateAdmins , err := findTemplateAdmins (ctx , db , stats )
@@ -147,7 +150,7 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
147
150
continue
148
151
}
149
152
150
- if ! reportLog .LastGeneratedAt .IsZero () && reportLog .LastGeneratedAt .Add (failedWorkspaceBuildsReportFrequencyDays * 24 * time . Hour ).After (now ) {
153
+ if ! reportLog .LastGeneratedAt .IsZero () && reportLog .LastGeneratedAt .Add (failedWorkspaceBuildsReportFrequency ).After (now ) {
151
154
// report generated recently, no need to send it now
152
155
continue
153
156
}
@@ -191,27 +194,15 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
191
194
192
195
err = db .DeleteOldReportGeneratorLogs (ctx , database.DeleteOldReportGeneratorLogsParams {
193
196
NotificationTemplateID : notifications .TemplateWorkspaceBuildsFailedReport ,
194
- Before : dbtime .Time (now .Add (- failedWorkspaceBuildsReportFrequencyDays * 24 * time . Hour - time .Hour )).UTC (),
197
+ Before : dbtime .Time (now .Add (- failedWorkspaceBuildsReportFrequency - time .Hour )).UTC (),
195
198
})
196
199
if err != nil {
197
200
return xerrors .Errorf ("unable to delete old report generator logs: %w" , err )
198
201
}
199
202
return nil
200
203
}
201
204
202
- func buildDataForReportFailedWorkspaceBuilds (frequencyDays int , stats database.GetWorkspaceBuildStatsByTemplatesRow , failedBuilds []database.GetFailedWorkspaceBuildsByTemplateIDRow ) map [string ]any {
203
- // Format frequency label
204
- var frequencyLabel string
205
- if frequencyDays == 7 {
206
- frequencyLabel = "week"
207
- } else {
208
- var plural string
209
- if frequencyDays > 1 {
210
- plural = "s"
211
- }
212
- frequencyLabel = fmt .Sprintf ("%d day%s" , frequencyDays , plural )
213
- }
214
-
205
+ func buildDataForReportFailedWorkspaceBuilds (stats database.GetWorkspaceBuildStatsByTemplatesRow , failedBuilds []database.GetFailedWorkspaceBuildsByTemplateIDRow ) map [string ]any {
215
206
// Sorting order: template_version_name ASC, workspace build number DESC
216
207
sort .Slice (failedBuilds , func (i , j int ) bool {
217
208
if failedBuilds [i ].TemplateVersionName != failedBuilds [j ].TemplateVersionName {
@@ -240,22 +231,24 @@ func buildDataForReportFailedWorkspaceBuilds(frequencyDays int, stats database.G
240
231
continue
241
232
}
242
233
234
+ tv := templateVersions [c - 1 ]
243
235
//nolint:errorlint,forcetypeassert // only this function prepares the notification model
244
- builds := templateVersions [ c - 1 ] ["failed_builds" ].([]map [string ]any )
236
+ builds := tv ["failed_builds" ].([]map [string ]any )
245
237
builds = append (builds , map [string ]any {
246
238
"workspace_owner_username" : failedBuild .WorkspaceOwnerUsername ,
247
239
"workspace_name" : failedBuild .WorkspaceName ,
248
240
"build_number" : failedBuild .WorkspaceBuildNumber ,
249
241
})
250
- templateVersions [ c - 1 ] ["failed_builds" ] = builds
242
+ tv ["failed_builds" ] = builds
251
243
//nolint:errorlint,forcetypeassert // only this function prepares the notification model
252
- templateVersions [c - 1 ]["failed_count" ] = templateVersions [c - 1 ]["failed_count" ].(int ) + 1
244
+ tv ["failed_count" ] = tv ["failed_count" ].(int ) + 1
245
+ templateVersions [c - 1 ] = tv
253
246
}
254
247
255
248
return map [string ]any {
256
249
"failed_builds" : stats .FailedBuilds ,
257
250
"total_builds" : stats .TotalBuilds ,
258
- "report_frequency" : frequencyLabel ,
251
+ "report_frequency" : failedWorkspaceBuildsReportFrequencyLabel ,
259
252
"template_versions" : templateVersions ,
260
253
}
261
254
}
0 commit comments