From 9e726028c31865560b85a5ac38e4d673253c125d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Thu, 7 Nov 2019 12:56:05 +0100 Subject: [PATCH] Introduce flag to recompute summaries from raw events instead of using aggregations. --- main.go | 7 +------ routes/summary.go | 13 ++++++++++--- services/aggregation.go | 2 +- services/summary.go | 14 ++++++++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index f2d9e44..477a505 100644 --- a/main.go +++ b/main.go @@ -170,12 +170,7 @@ func migrateLanguages(db *gorm.DB, cfg *models.Config) { func addDefaultUser(db *gorm.DB, cfg *models.Config) { pw := md5.Sum([]byte(models.DefaultPassword)) pwString := hex.EncodeToString(pw[:]) - var err error - apiKey := uuid.Must(uuid.NewV4(), err).String() - if err != nil { - log.Println("Unable to create api key.") - log.Fatal(err) - } + apiKey := uuid.NewV4().String() u := &models.User{ID: models.DefaultUser, Password: pwString, ApiKey: apiKey} result := db.FirstOrCreate(u, &models.User{ID: u.ID}) if result.Error != nil { diff --git a/routes/summary.go b/routes/summary.go index 651236d..b120d41 100644 --- a/routes/summary.go +++ b/routes/summary.go @@ -10,6 +10,7 @@ import ( "github.com/n1try/wakapi/services" "github.com/n1try/wakapi/utils" cache "github.com/patrickmn/go-cache" + uuid "github.com/satori/go.uuid" ) const ( @@ -67,21 +68,27 @@ func (h *SummaryHandler) Get(w http.ResponseWriter, r *http.Request) { } live := (params.Get("live") != "" && params.Get("live") != "false") || interval == IntervalToday + recompute := (params.Get("recompute") != "" && params.Get("recompute") != "false") to := utils.StartOfDay() if live { to = time.Now() } var summary *models.Summary - cacheKey := getHash([]time.Time{from, to}, user) + var cacheKey string + if !recompute { + cacheKey = getHash([]time.Time{from, to}, user) + } else { + cacheKey = uuid.NewV4().String() + } if cachedSummary, ok := h.Cache.Get(cacheKey); !ok { // Cache Miss - summary, err = h.SummarySrvc.Construct(from, to, user) // 'to' is always constant + summary, err = h.SummarySrvc.Construct(from, to, user, recompute) // 'to' is always constant if err != nil { w.WriteHeader(http.StatusInternalServerError) return } - if !live { + if !live && !recompute { h.Cache.Set(cacheKey, summary, cache.DefaultExpiration) } } else { diff --git a/services/aggregation.go b/services/aggregation.go index 9158127..e834507 100644 --- a/services/aggregation.go +++ b/services/aggregation.go @@ -53,7 +53,7 @@ func (srv *AggregationService) Schedule() { func (srv *AggregationService) summaryWorker(jobs <-chan *AggregationJob, summaries chan<- *models.Summary) { for job := range jobs { - if summary, err := srv.SummaryService.Construct(job.From, job.To, &models.User{ID: job.UserID}); err != nil { + if summary, err := srv.SummaryService.Construct(job.From, job.To, &models.User{ID: job.UserID}, true); err != nil { log.Printf("Failed to generate summary (%v, %v, %s) – %v.\n", job.From, job.To, job.UserID, err) } else { log.Printf("Successfully generated summary (%v, %v, %s).\n", job.From, job.To, job.UserID) diff --git a/services/summary.go b/services/summary.go index 91c8db4..ca809f8 100644 --- a/services/summary.go +++ b/services/summary.go @@ -22,10 +22,16 @@ type Interval struct { End time.Time } -func (srv *SummaryService) Construct(from, to time.Time, user *models.User) (*models.Summary, error) { - existingSummaries, err := srv.GetByUserWithin(user, from, to) - if err != nil { - return nil, err +func (srv *SummaryService) Construct(from, to time.Time, user *models.User, recompute bool) (*models.Summary, error) { + var existingSummaries []*models.Summary + if recompute { + existingSummaries = make([]*models.Summary, 0) + } else { + summaries, err := srv.GetByUserWithin(user, from, to) + if err != nil { + return nil, err + } + existingSummaries = summaries } missingIntervals := getMissingIntervals(from, to, existingSummaries)