MCPcopy Index your code
hub / github.com/coder/coder / NewReportGenerator

Function NewReportGenerator

coderd/notifications/reports/generator.go:28–87  ·  view source on GitHub ↗
(ctx context.Context, logger slog.Logger, db database.Store, enqueuer notifications.Enqueuer, clk quartz.Clock)

Source from the content-addressed store, hash-verified

26)
27
28func NewReportGenerator(ctx context.Context, logger slog.Logger, db database.Store, enqueuer notifications.Enqueuer, clk quartz.Clock) io.Closer {
29 closed := make(chan struct{})
30
31 ctx, cancelFunc := context.WithCancel(ctx)
32 //nolint:gocritic // The system generates periodic reports without direct user input.
33 ctx = dbauthz.AsSystemRestricted(ctx)
34
35 // Start the ticker with the initial delay.
36 ticker := clk.NewTicker(delay)
37 ticker.Stop()
38 doTick := func(start time.Time) {
39 defer ticker.Reset(delay)
40 // Start a transaction to grab advisory lock, we don't want to run generator jobs at the same time (multiple replicas).
41 if err := db.InTx(func(tx database.Store) error {
42 // Acquire a lock to ensure that only one instance of the generator is running at a time.
43 ok, err := tx.TryAcquireLock(ctx, database.LockIDNotificationsReportGenerator)
44 if err != nil {
45 return xerrors.Errorf("failed to acquire report generator lock: %w", err)
46 }
47 if !ok {
48 logger.Debug(ctx, "unable to acquire lock for generating periodic reports, skipping")
49 return nil
50 }
51
52 err = reportFailedWorkspaceBuilds(ctx, logger, tx, enqueuer, clk)
53 if err != nil {
54 return xerrors.Errorf("unable to generate reports with failed workspace builds: %w", err)
55 }
56
57 logger.Info(ctx, "report generator finished", slog.F("duration", clk.Since(start)))
58
59 return nil
60 }, nil); err != nil {
61 logger.Error(ctx, "failed to generate reports", slog.Error(err))
62 return
63 }
64 }
65
66 go func() {
67 defer close(closed)
68 defer ticker.Stop()
69 // Force an initial tick.
70 doTick(dbtime.Time(clk.Now()).UTC())
71 for {
72 select {
73 case <-ctx.Done():
74 logger.Debug(ctx, "closing report generator")
75 return
76 case tick := <-ticker.C:
77 ticker.Stop()
78
79 doTick(dbtime.Time(tick).UTC())
80 }
81 }
82 }()
83 return &reportGenerator{
84 cancel: cancelFunc,
85 closed: closed,

Callers 1

ServerMethod · 0.92

Calls 11

AsSystemRestrictedFunction · 0.92
TimeFunction · 0.92
StopMethod · 0.65
ResetMethod · 0.65
InTxMethod · 0.65
TryAcquireLockMethod · 0.65
ErrorfMethod · 0.45
InfoMethod · 0.45
ErrorMethod · 0.45
DoneMethod · 0.45

Tested by

no test coverage detected