aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-26 12:08:01 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-26 12:08:01 +0100
commitafccdb6cffa7bec1fb677819f3e721a0762c3e8a (patch)
treef1bc50be92e8ab767c5ad5931919ebd2a2e39006
parentbd660019eea61a63ed75a8b5d6a7435e37434908 (diff)
dashboard/app: preserve at least 1 crash per manager
When purging crashes we currently sort by priority (manager) first, as the result if we have enough month-old crashes on upstream, we stop saving any new crashes on other branches. Sort by time first, but keep at least 1 crash per manager.
-rw-r--r--dashboard/app/api.go48
-rw-r--r--dashboard/app/index.yaml2
2 files changed, 31 insertions, 19 deletions
diff --git a/dashboard/app/api.go b/dashboard/app/api.go
index 98ca78e9b..cf5a9424b 100644
--- a/dashboard/app/api.go
+++ b/dashboard/app/api.go
@@ -567,8 +567,7 @@ func reportCrash(c context.Context, ns string, req *dashapi.Crash) (*Bug, error)
}
func purgeOldCrashes(c context.Context, bug *Bug, bugKey *datastore.Key) {
- const batchSize = 10 // delete at most that many at once
- if bug.NumCrashes <= maxCrashes {
+ if bug.NumCrashes <= maxCrashes || bug.NumCrashes%10 != 0 {
return
}
var crashes []*Crash
@@ -577,9 +576,6 @@ func purgeOldCrashes(c context.Context, bug *Bug, bugKey *datastore.Key) {
Filter("ReproC=", 0).
Filter("ReproSyz=", 0).
Filter("Reported=", time.Time{}).
- Order("ReportLen").
- Order("Time").
- Limit(maxCrashes+batchSize).
GetAll(c, &crashes)
if err != nil {
log.Errorf(c, "failed to fetch purge crashes: %v", err)
@@ -588,32 +584,50 @@ func purgeOldCrashes(c context.Context, bug *Bug, bugKey *datastore.Key) {
if len(keys) <= maxCrashes {
return
}
- keys = keys[:len(keys)-maxCrashes]
+ keyMap := make(map[*Crash]*datastore.Key)
+ for i, crash := range crashes {
+ keyMap[crash] = keys[i]
+ }
+ // Newest first.
+ sort.Slice(crashes, func(i, j int) bool {
+ return crashes[i].Time.After(crashes[j].Time)
+ })
+ // Find latest crash on each manager.
+ latestOnManager := make(map[string]*Crash)
+ for _, crash := range crashes {
+ if latestOnManager[crash.Manager] == nil {
+ latestOnManager[crash.Manager] = crash
+ }
+ }
+ // Oldest first but move latest crash on each manager to the end (preserve them).
+ sort.Slice(crashes, func(i, j int) bool {
+ latesti := latestOnManager[crashes[i].Manager] == crashes[i]
+ latestj := latestOnManager[crashes[j].Manager] == crashes[j]
+ if latesti != latestj {
+ return latestj
+ }
+ return crashes[i].Time.Before(crashes[j].Time)
+ })
crashes = crashes[:len(crashes)-maxCrashes]
- var texts []*datastore.Key
+ var toDelete []*datastore.Key
for _, crash := range crashes {
if crash.ReproSyz != 0 || crash.ReproC != 0 || !crash.Reported.IsZero() {
log.Errorf(c, "purging reproducer?")
continue
}
+ toDelete = append(toDelete, keyMap[crash])
if crash.Log != 0 {
- texts = append(texts, datastore.NewKey(c, "CrashLog", "", crash.Log, nil))
+ toDelete = append(toDelete, datastore.NewKey(c, "CrashLog", "", crash.Log, nil))
}
if crash.Report != 0 {
- texts = append(texts, datastore.NewKey(c, "CrashReport", "", crash.Report, nil))
- }
- }
- if len(texts) != 0 {
- if err := datastore.DeleteMulti(c, texts); err != nil {
- log.Errorf(c, "failed to delete old crash texts: %v", err)
- return
+ toDelete = append(toDelete, datastore.NewKey(c, "CrashReport", "", crash.Report, nil))
}
}
- if err := datastore.DeleteMulti(c, keys); err != nil {
+ if err := datastore.DeleteMulti(c, toDelete); err != nil {
log.Errorf(c, "failed to delete old crashes: %v", err)
return
}
- log.Infof(c, "deleted %v crashes for bug %q", len(keys), bug.Title)
+ log.Infof(c, "deleted %v crashes for bug %q", len(crashes), bug.Title)
}
func apiReportFailedRepro(c context.Context, ns string, r *http.Request) (interface{}, error) {
diff --git a/dashboard/app/index.yaml b/dashboard/app/index.yaml
index eab86934e..ec0fe62a2 100644
--- a/dashboard/app/index.yaml
+++ b/dashboard/app/index.yaml
@@ -41,8 +41,6 @@ indexes:
- name: Reported
- name: ReproC
- name: ReproSyz
- - name: ReportLen
- - name: Time
- kind: Crash
ancestor: yes