Skip to content

Commit

Permalink
chore: better missed maintain loop reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
charlie0129 committed Feb 17, 2025
1 parent f9d889e commit 327c337
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
28 changes: 28 additions & 0 deletions loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ func (r *MaintainLoopRecorder) GetRecordsIn(last time.Duration) int {
r.mu.Lock()
defer r.mu.Unlock()

// The last record must be within the last duration.
if len(r.LastMaintainLoopTimes) > 0 && time.Since(r.LastMaintainLoopTimes[len(r.LastMaintainLoopTimes)-1]) >= loopInterval+time.Second {
return 0
}

// Find continuous records from the end of the list.
// Continuous records are defined as the time difference between
// two adjacent records is less than loopInterval+1 second.
Expand All @@ -73,6 +78,27 @@ func (r *MaintainLoopRecorder) GetRecordsIn(last time.Duration) int {
return count
}

func (r *MaintainLoopRecorder) GetRecordsRelativeToCurrent(last time.Duration) []time.Duration {
r.mu.Lock()
defer r.mu.Unlock()

if len(r.LastMaintainLoopTimes) == 0 {
return nil
}

current := time.Now()
var records []time.Duration
for i := len(r.LastMaintainLoopTimes) - 1; i >= 0; i-- {
record := r.LastMaintainLoopTimes[i]
if current.Sub(record) > last {
break
}
records = append(records, current.Sub(record))
}

return records
}

// GetLastRecord returns the last record.
func (r *MaintainLoopRecorder) GetLastRecord() time.Time {
r.mu.Lock()
Expand Down Expand Up @@ -183,6 +209,7 @@ func maintainLoopInner() bool {
maintainLoopCount := loopRecorder.GetRecordsIn(time.Minute * 2)
expectedMaintainLoopCount := int(time.Minute * 2 / loopInterval)
minMaintainLoopCount := expectedMaintainLoopCount - 1
relativeTimes := loopRecorder.GetRecordsRelativeToCurrent(time.Minute * 2)
// If maintain loop is missed too many times, we assume the system is in a rapid sleep/wake loop, or macOS
// haven't sent the sleep notification but the system is actually sleep/waking up. In either case, we should
// not enable charging, which will cause unexpected charging.
Expand All @@ -199,6 +226,7 @@ func maintainLoopInner() bool {
"maintainLoopCount": maintainLoopCount,
"expectedMaintainLoopCount": expectedMaintainLoopCount,
"minMaintainLoopCount": minMaintainLoopCount,
"relativeTimes": relativeTimes,
}).Infof("Battery charge is below lower limit, but too many missed maintain loops are missed. Will wait until maintain loops are stable")
return true
}
Expand Down
23 changes: 22 additions & 1 deletion loop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ func TestMaintainLoopRecorder_GetRecordsIn(t *testing.T) {
fields: fields{
MaxRecordCount: 10,
LastMaintainLoopTimes: []time.Time{
time.Now().Add(-time.Second * 70).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 60).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 40).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 30).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 20).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 10).Add(-10 * time.Millisecond),
Expand All @@ -52,7 +54,26 @@ func TestMaintainLoopRecorder_GetRecordsIn(t *testing.T) {
args: args{
last: time.Second * 50,
},
want: 3,
want: 4,
},
{
name: "test continuous records 2",
fields: fields{
MaxRecordCount: 10,
LastMaintainLoopTimes: []time.Time{
time.Now().Add(-time.Second * 70).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 60).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 40).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 30).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 20).Add(-10 * time.Millisecond),
time.Now().Add(-time.Second * 15).Add(-10 * time.Millisecond),
},
mu: &sync.Mutex{},
},
args: args{
last: time.Second * 50,
},
want: 0,
},
}
for _, tt := range tests {
Expand Down

0 comments on commit 327c337

Please sign in to comment.