mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
fix: critical summary computation bug (faulty intervals)
fix: doubly included heartbeats fix: cross-day heartbeats are ignored for consistency
This commit is contained in:
parent
44b6efb6ee
commit
54a944ec41
@ -46,7 +46,7 @@ func (srv *HeartbeatService) GetAllWithin(from, to time.Time, user *models.User)
|
|||||||
if err := srv.Db.
|
if err := srv.Db.
|
||||||
Where(&models.Heartbeat{UserID: user.ID}).
|
Where(&models.Heartbeat{UserID: user.ID}).
|
||||||
Where("time >= ?", from).
|
Where("time >= ?", from).
|
||||||
Where("time <= ?", to).
|
Where("time < ?", to).
|
||||||
Order("time asc").
|
Order("time asc").
|
||||||
Find(&heartbeats).Error; err != nil {
|
Find(&heartbeats).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/muety/wakapi/models"
|
"github.com/muety/wakapi/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const HeartbeatDiffThreshold = 2 * time.Minute
|
||||||
|
|
||||||
type SummaryService struct {
|
type SummaryService struct {
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
@ -218,9 +220,16 @@ func (srv *SummaryService) aggregateBy(heartbeats []*models.Heartbeat, summaryTy
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
timePassed := h.Time.Time().Sub(heartbeats[i-1].Time.Time())
|
t1, t2, tdiff := h.Time.Time(), heartbeats[i-1].Time.Time(), time.Duration(0)
|
||||||
timeThresholded := math.Min(float64(timePassed), float64(time.Duration(2)*time.Minute))
|
// This is a hack. The time difference between two heartbeats from two subsequent day (e.g. 23:59:59 and 00:00:01) are ignored.
|
||||||
durations[key] += time.Duration(int64(timeThresholded))
|
// This is to prevent a discrepancy between summaries computed solely from heartbeats and summaries involving pre-aggregated per-day summaries.
|
||||||
|
// For the latter, a duration is already pre-computed and information about individual heartbeats is lost, so there can be no cross-day overflow.
|
||||||
|
// Essentially, we simply ignore such edge-case heartbeats here, which makes the eventual total duration potentially a bit shorter.
|
||||||
|
if t1.Day() == t2.Day() {
|
||||||
|
timePassed := t1.Sub(t2)
|
||||||
|
tdiff = time.Duration(int64(math.Min(float64(timePassed), float64(HeartbeatDiffThreshold))))
|
||||||
|
}
|
||||||
|
durations[key] += tdiff
|
||||||
}
|
}
|
||||||
|
|
||||||
items := make([]*models.SummaryItem, 0)
|
items := make([]*models.SummaryItem, 0)
|
||||||
@ -269,7 +278,7 @@ func getMissingIntervals(from, to time.Time, existingSummaries []*models.Summary
|
|||||||
|
|
||||||
// Post
|
// Post
|
||||||
if to.After(existingSummaries[len(existingSummaries)-1].ToTime) {
|
if to.After(existingSummaries[len(existingSummaries)-1].ToTime) {
|
||||||
intervals = append(intervals, &Interval{to, existingSummaries[len(existingSummaries)-1].ToTime})
|
intervals = append(intervals, &Interval{existingSummaries[len(existingSummaries)-1].ToTime, to})
|
||||||
}
|
}
|
||||||
|
|
||||||
return intervals
|
return intervals
|
||||||
|
@ -1 +1 @@
|
|||||||
1.12.3
|
1.12.4
|
Loading…
Reference in New Issue
Block a user