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

Method FlushToDB

coderd/boundaryusage/tracker.go:73–134  ·  view source on GitHub ↗

FlushToDB writes stats to the database. For unique counts, cumulative values are used on UPDATE (replacing the DB value) while delta values are used on INSERT (starting fresh). Request counts are always deltas, accumulated in DB. All deltas are reset immediately after snapshot so Track() calls durin

(ctx context.Context, db database.Store, replicaID uuid.UUID)

Source from the content-addressed store, hash-verified

71// All deltas are reset immediately after snapshot so Track() calls during the
72// DB operation are preserved for the next flush.
73func (t *Tracker) FlushToDB(ctx context.Context, db database.Store, replicaID uuid.UUID) error {
74 t.mu.Lock()
75 if !t.usageSinceLastFlush {
76 t.mu.Unlock()
77 return nil
78 }
79
80 // Snapshot all values.
81 workspaceCount := int64(len(t.workspaces)) // cumulative, for UPDATE
82 userCount := int64(len(t.users)) // cumulative, for UPDATE
83 workspaceDelta := int64(len(t.workspacesDelta)) // delta, for INSERT
84 userDelta := int64(len(t.usersDelta)) // delta, for INSERT
85 allowed := t.allowedRequests // delta, accumulated in DB
86 denied := t.deniedRequests // delta, accumulated in DB
87
88 // Reset all deltas immediately so Track() calls during the DB operation
89 // below are preserved for the next flush.
90 t.workspacesDelta = make(map[uuid.UUID]struct{})
91 t.usersDelta = make(map[uuid.UUID]struct{})
92 t.allowedRequests = 0
93 t.deniedRequests = 0
94 t.usageSinceLastFlush = false
95 t.mu.Unlock()
96
97 //nolint:gocritic // This is the actual package doing boundary usage tracking.
98 authCtx := dbauthz.AsBoundaryUsageTracker(ctx)
99 err := db.InTx(func(tx database.Store) error {
100 // The advisory lock ensures a clean period cutover by preventing
101 // this upsert from racing with the aggregate+delete in
102 // GetAndResetBoundaryUsageSummary. Without it, upserted data
103 // could be lost or miscounted across periods.
104 if err := tx.AcquireLock(authCtx, database.LockIDBoundaryUsageStats); err != nil {
105 return err
106 }
107 _, err := tx.UpsertBoundaryUsageStats(authCtx, database.UpsertBoundaryUsageStatsParams{
108 ReplicaID: replicaID,
109 UniqueWorkspacesCount: workspaceCount, // cumulative, for UPDATE
110 UniqueUsersCount: userCount, // cumulative, for UPDATE
111 UniqueWorkspacesDelta: workspaceDelta, // delta, for INSERT
112 UniqueUsersDelta: userDelta, // delta, for INSERT
113 AllowedRequests: allowed,
114 DeniedRequests: denied,
115 })
116 return err
117 }, nil)
118
119 // Always reset cumulative counts to prevent unbounded memory growth (e.g.
120 // if the DB is unreachable). Copy delta maps to preserve any Track() calls
121 // that occurred during the DB operation above.
122 t.mu.Lock()
123 t.workspaces = make(map[uuid.UUID]struct{})
124 t.users = make(map[uuid.UUID]struct{})
125 for id := range t.workspacesDelta {
126 t.workspaces[id] = struct{}{}
127 }
128 for id := range t.usersDelta {
129 t.users[id] = struct{}{}
130 }

Calls 6

AsBoundaryUsageTrackerFunction · 0.92
InTxMethod · 0.65
AcquireLockMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45