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

Method purgeTick

coderd/database/dbpurge/dbpurge.go:185–397  ·  view source on GitHub ↗

purgeTick performs a single purge iteration. It returns an error if the purge fails.

(ctx context.Context, db database.Store, start time.Time)

Source from the content-addressed store, hash-verified

183// purgeTick performs a single purge iteration. It returns an error if the
184// purge fails.
185func (i *instance) purgeTick(ctx context.Context, db database.Store, start time.Time) error {
186 // Read chat configs outside the tx so a corrupt value can't
187 // poison subsequent queries. On config read errors, log and stash
188 // the error, then run unrelated purges best-effort. Retention and
189 // auto-archive errors skip only the conversation purge and
190 // auto-archive work. Debug retention errors skip only the debug
191 // purge. purgeTick returns chatConfigErr after the tx so the failed
192 // iteration is operator-visible via metric and logs.
193 chatRetentionDays, chatRetentionErr := db.GetChatRetentionDays(ctx)
194 if chatRetentionErr != nil {
195 i.logger.Error(ctx, "failed to read chat retention config: skipping chat purge and auto-archive this tick", slog.Error(chatRetentionErr))
196 }
197
198 chatAutoArchiveDays, chatAutoArchiveErr := db.GetChatAutoArchiveDays(ctx, codersdk.DefaultChatAutoArchiveDays)
199 if chatAutoArchiveErr != nil {
200 i.logger.Error(ctx, "failed to read chat auto-archive config: skipping chat purge and auto-archive this tick", slog.Error(chatAutoArchiveErr))
201 }
202
203 chatDebugRetentionDays, chatDebugRetentionErr := db.GetChatDebugRetentionDays(ctx, codersdk.DefaultChatDebugRetentionDays)
204 if chatDebugRetentionErr != nil {
205 i.logger.Error(ctx, "failed to read chat debug retention config: skipping chat debug purge this tick", slog.Error(chatDebugRetentionErr))
206 }
207
208 chatRetentionConfigErr := errors.Join(chatRetentionErr, chatAutoArchiveErr)
209 chatConfigErr := errors.Join(chatRetentionConfigErr, chatDebugRetentionErr)
210
211 // Populated inside the tx; dispatched post-commit.
212 var archivedChats []database.AutoArchiveInactiveChatsRow
213
214 // Start a transaction to grab advisory lock, we don't want to run
215 // multiple purges at the same time (multiple replicas).
216 err := db.InTx(func(tx database.Store) error {
217 // Acquire a lock to ensure that only one instance of the
218 // purge is running at a time.
219 ok, err := tx.TryAcquireLock(ctx, database.LockIDDBPurge)
220 if err != nil {
221 return err
222 }
223 if !ok {
224 i.logger.Debug(ctx, "unable to acquire lock for purging old database entries, skipping")
225 return nil
226 }
227
228 var purgedWorkspaceAgentLogs int64
229 workspaceAgentLogsRetention := i.vals.Retention.WorkspaceAgentLogs.Value()
230 if workspaceAgentLogsRetention > 0 {
231 deleteOldWorkspaceAgentLogsBefore := start.Add(-workspaceAgentLogsRetention)
232 purgedWorkspaceAgentLogs, err = tx.DeleteOldWorkspaceAgentLogs(ctx, deleteOldWorkspaceAgentLogsBefore)
233 if err != nil {
234 return xerrors.Errorf("failed to delete old workspace agent logs: %w", err)
235 }
236 }
237 if err := tx.DeleteOldWorkspaceAgentStats(ctx); err != nil {
238 return xerrors.Errorf("failed to delete old workspace agent stats: %w", err)
239 }
240 if err := tx.DeleteOldProvisionerDaemons(ctx); err != nil {
241 return xerrors.Errorf("failed to delete old provisioner daemons: %w", err)
242 }

Callers 2

NewFunction · 0.95
TestDBPurgeAuthorizationFunction · 0.95

Calls 15

purgeChatsInTxMethod · 0.95
TimeFunction · 0.92
AsAIBridgedFunction · 0.92
DefaultTXOptionsFunction · 0.92
DurationMethod · 0.80
WithLabelValuesMethod · 0.80
GetChatRetentionDaysMethod · 0.65
InTxMethod · 0.65
TryAcquireLockMethod · 0.65

Tested by 1

TestDBPurgeAuthorizationFunction · 0.76