add regeneration intent log (#26354)

This commit is contained in:
Josh Black
2024-04-12 09:28:16 -07:00
committed by GitHub
parent 691bf9b3a7
commit e94163e475
2 changed files with 122 additions and 0 deletions

View File

@@ -1175,6 +1175,32 @@ func (c *Core) setupActivityLogLocked(ctx context.Context, wg *sync.WaitGroup) e
return nil
}
func (a *ActivityLog) createRegenerationIntentLog(ctx context.Context, now time.Time) (*ActivityIntentLog, error) {
intentLog := &ActivityIntentLog{}
segments, err := a.availableLogs(ctx)
if err != nil {
return nil, fmt.Errorf("error fetching available logs: %w", err)
}
for i, segment := range segments {
if timeutil.IsCurrentMonth(segment, now) {
continue
}
intentLog.PreviousMonth = segment.Unix()
if i > 0 {
intentLog.NextMonth = segments[i-1].Unix()
break
}
}
if intentLog.NextMonth == 0 || intentLog.PreviousMonth == 0 {
return nil, fmt.Errorf("insufficient data to create a regeneration intent log")
}
return intentLog, nil
}
// stopActivityLogLocked removes the ActivityLog from Core
// and frees any resources.
// this function should be called with activityLogLock

View File

@@ -662,6 +662,102 @@ func TestActivityLog_availableLogs(t *testing.T) {
}
}
// TestActivityLog_createRegenerationIntentLog tests that we can correctly create a regeneration intent log given the segments in storage
func TestActivityLog_createRegenerationIntentLog(t *testing.T) {
testCases := []struct {
name string
times []time.Time
expectedLog *ActivityIntentLog
expectedError bool
}{
{
"no segments",
[]time.Time{},
nil,
true,
},
{
"one segment",
[]time.Time{
time.Date(2024, 4, 4, 10, 54, 12, 0, time.UTC),
},
nil,
true,
},
{
"most recent segment is 3 months ago",
[]time.Time{
time.Date(2024, 1, 4, 10, 54, 12, 0, time.UTC),
time.Date(2024, 1, 3, 10, 54, 12, 0, time.UTC),
},
&ActivityIntentLog{NextMonth: 1704365652, PreviousMonth: 1704279252},
false,
},
{
"lots of segments",
[]time.Time{
// two this month
time.Date(2024, 4, 4, 10, 54, 12, 0, time.UTC),
time.Date(2024, 4, 6, 10, 54, 12, 0, time.UTC),
// three last month
time.Date(2024, 3, 3, 10, 54, 12, 0, time.UTC),
time.Date(2024, 3, 6, 10, 54, 12, 0, time.UTC),
time.Date(2024, 3, 14, 10, 54, 12, 0, time.UTC),
// two the month before that
time.Date(2024, 2, 10, 10, 54, 12, 0, time.UTC),
time.Date(2024, 2, 17, 10, 54, 12, 0, time.UTC),
},
&ActivityIntentLog{NextMonth: 1712228052, PreviousMonth: 1710413652},
false,
},
}
core, _, _ := TestCoreUnsealed(t)
a := core.activityLog
now := time.Date(2024, 4, 10, 10, 54, 12, 0, time.UTC)
ctx := context.Background()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
deletePaths := make([]string, 0)
// insert the times we're given
paths := make([]string, 0, len(tc.times))
for _, tm := range tc.times {
paths = append(paths, fmt.Sprintf("entity/%d/1", tm.Unix()))
}
for _, subPath := range paths {
fullPath := ActivityLogPrefix + subPath
WriteToStorage(t, core, fullPath, []byte("test"))
deletePaths = append(deletePaths, fullPath)
}
// regenerate the log
intentLog, err := a.createRegenerationIntentLog(context.Background(), now)
if tc.expectedError && err == nil {
t.Fatal("expected an error and got none")
}
if !tc.expectedError && err != nil {
t.Fatal(err)
}
// verify it's what we expect
if diff := deep.Equal(intentLog, tc.expectedLog); len(diff) != 0 {
t.Errorf("got=%v, expected=%v, diff=%v", intentLog, tc.expectedLog, diff)
}
// delete everything we wrote so the next test starts fresh
for _, p := range deletePaths {
err := core.barrier.Delete(ctx, p)
if err != nil {
t.Fatal(err)
}
}
})
}
}
// TestActivityLog_MultipleFragmentsAndSegments adds 4000 clients to a fragment
// and saves it and reads it. The test then adds 4000 more clients and calls
// receivedFragment with 200 more entities. The current segment is saved to