Added database.change_batch_retention, deleting old change batches
Each save that records a batch also deletes, in the same transaction, the batches older than database.change_batch_retention (30 days by default; 0 or less keeps them for ever), with their records of opportunities. A client still holding a deleted batch gets 410 Gone from ?changed_after= and reloads the whole list, as for any unknown batch.
This commit is contained in:
1 parent
1988d07a29
commit
65e5bc6b26
10 files changed
+153
-19
No files matched your search
+19
-6
@@ -51,6 +51,9 @@ const DefaultListLimit = 50
|
||||
// concurrent use.
|
||||
type Store struct {
|
||||
db *sqlx.DB
|
||||
// changeBatchRetention is how long change batches are kept; 0 or less
|
||||
// means for ever (see WithChangeBatchRetention).
|
||||
changeBatchRetention time.Duration
|
||||
}
|
||||
|
||||
// SaveMultipleResult reports what SaveOpportunities changed.
|
||||
@@ -243,7 +246,8 @@ func Open(ctx context.Context, path string, opts ...Option) (*Store, error) {
|
||||
}
|
||||
|
||||
return &Store{
|
||||
db: sqlx.NewDb(sqldb, "sqlite3"),
|
||||
db: sqlx.NewDb(sqldb, "sqlite3"),
|
||||
changeBatchRetention: settings.changeBatchRetention,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -307,7 +311,7 @@ func (s *Store) SaveOpportunity(
|
||||
return SaveResult{}, err
|
||||
}
|
||||
|
||||
_, err = recordChangeBatch(
|
||||
_, err = s.recordChangeBatch(
|
||||
ctx,
|
||||
tx,
|
||||
changedUUIDs([]*types.Opportunity{opportunity}, []SaveResult{result}),
|
||||
@@ -387,7 +391,7 @@ func (s *Store) SaveOpportunities(
|
||||
total.AddedClassifications = added
|
||||
total.RemovedClassificationIDs = removed
|
||||
|
||||
total.ChangeBatch, err = recordChangeBatch(
|
||||
total.ChangeBatch, err = s.recordChangeBatch(
|
||||
ctx, tx, changedUUIDs(opportunities, total.OpportunityResults),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -465,14 +469,15 @@ func changedUUIDs(
|
||||
|
||||
// recordChangeBatch records a change batch of the opportunities uuids inside
|
||||
// tx and returns its hash, or "" without recording anything if uuids is
|
||||
// empty.
|
||||
// empty. Batches older than the store's retention are deleted (see
|
||||
// WithChangeBatchRetention).
|
||||
//
|
||||
// The batch's created_at is the current time, or just after the newest
|
||||
// batch's if that isn't later (the clock went back, or two batches came
|
||||
// within its resolution), so batches are ordered by created_at. tx holds the
|
||||
// write lock from its start (see dsn), so no other batch can be recorded in
|
||||
// between.
|
||||
func recordChangeBatch(
|
||||
func (s *Store) recordChangeBatch(
|
||||
ctx context.Context, tx *sqlx.Tx, uuids []string,
|
||||
) (string, error) {
|
||||
if len(uuids) == 0 {
|
||||
@@ -506,6 +511,14 @@ func recordChangeBatch(
|
||||
}
|
||||
}
|
||||
|
||||
if s.changeBatchRetention > 0 {
|
||||
cutoff := createdAt.Add(-s.changeBatchRetention)
|
||||
_, err = tx.ExecContext(ctx, deleteChangeBatchesBefore, cutoff)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("deleting old change batches: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return hash, nil
|
||||
}
|
||||
|
||||
@@ -681,7 +694,7 @@ func (s *Store) SetMarks(
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = recordChangeBatch(ctx, tx, []string{marks.UUID})
|
||||
_, err = s.recordChangeBatch(ctx, tx, []string{marks.UUID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user