From cc5aab6cffa757b914df3e88b7d393987f7b97b1 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Mon, 2 May 2016 10:59:43 +0200 Subject: [PATCH] provider/boltmem: add alert subscription. This commit implements the Subscribe() and GetPending() methods for the bolt based alert provider. --- provider/boltmem/boltmem.go | 74 +++++++++++++++++++++++++++- template/internal/deftmpl/bindata.go | 2 +- ui/bindata.go | 74 ++++++++++++++-------------- 3 files changed, 110 insertions(+), 40 deletions(-) diff --git a/provider/boltmem/boltmem.go b/provider/boltmem/boltmem.go index 824242f0..e162e3e8 100644 --- a/provider/boltmem/boltmem.go +++ b/provider/boltmem/boltmem.go @@ -43,13 +43,83 @@ func NewAlerts(path string) (*Alerts, error) { // resolved and successfully notified about. // They are not guaranteed to be in chronological order. func (a *Alerts) Subscribe() provider.AlertIterator { - return nil + var ( + ch = make(chan *types.Alert, 200) + done = make(chan struct{}) + ) + alerts, err := a.getPending() + + a.mtx.Lock() + i := a.next + a.next++ + a.listeners[i] = ch + a.mtx.Unlock() + + go func() { + defer func() { + a.mtx.Lock() + delete(a.listeners, i) + close(ch) + a.mtx.Unlock() + }() + + for _, a := range alerts { + select { + case ch <- a: + case <-done: + return + } + } + + <-done + }() + + return provider.NewAlertIterator(ch, done, err) } // GetPending returns an iterator over all alerts that have // pending notifications. func (a *Alerts) GetPending() provider.AlertIterator { - return nil + var ( + ch = make(chan *types.Alert, 200) + done = make(chan struct{}) + ) + + alerts, err := a.getPending() + + go func() { + defer close(ch) + + for _, a := range alerts { + select { + case ch <- a: + case <-done: + return + } + } + }() + + return provider.NewAlertIterator(ch, done, err) +} + +func (a *Alerts) getPending() ([]*types.Alert, error) { + var alerts []*types.Alert + + err := a.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket(bktAlerts) + c := b.Cursor() + + for k, v := c.First(); k != nil; k, v = c.Next() { + var a types.Alert + if err := json.Unmarshal(v, &a); err != nil { + return err + } + alerts = append(alerts, &a) + } + + return nil + }) + return alerts, err } // Get returns the alert for a given fingerprint. diff --git a/template/internal/deftmpl/bindata.go b/template/internal/deftmpl/bindata.go index 0ae052bf..69b247ed 100644 --- a/template/internal/deftmpl/bindata.go +++ b/template/internal/deftmpl/bindata.go @@ -182,6 +182,7 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ "template": &bintree{nil, map[string]*bintree{ "default.tmpl": &bintree{templateDefaultTmpl, map[string]*bintree{}}, @@ -234,4 +235,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } - diff --git a/ui/bindata.go b/ui/bindata.go index 0adf18f1..2a783fb8 100644 --- a/ui/bindata.go +++ b/ui/bindata.go @@ -581,28 +581,28 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "ui/app/css/main.css": uiAppCssMainCss, - "ui/app/index.html": uiAppIndexHtml, - "ui/app/js/app.js": uiAppJsAppJs, - "ui/app/partials/alert.html": uiAppPartialsAlertHtml, - "ui/app/partials/alerts.html": uiAppPartialsAlertsHtml, - "ui/app/partials/route.html": uiAppPartialsRouteHtml, + "ui/app/css/main.css": uiAppCssMainCss, + "ui/app/index.html": uiAppIndexHtml, + "ui/app/js/app.js": uiAppJsAppJs, + "ui/app/partials/alert.html": uiAppPartialsAlertHtml, + "ui/app/partials/alerts.html": uiAppPartialsAlertsHtml, + "ui/app/partials/route.html": uiAppPartialsRouteHtml, "ui/app/partials/silence-form.html": uiAppPartialsSilenceFormHtml, - "ui/app/partials/silence.html": uiAppPartialsSilenceHtml, - "ui/app/partials/silences.html": uiAppPartialsSilencesHtml, - "ui/app/partials/status.html": uiAppPartialsStatusHtml, - "ui/bindata.go": uiBindataGo, - "ui/lib/angular-moment.min.js": uiLibAngularMomentMinJs, - "ui/lib/angular-resource.min.js": uiLibAngularResourceMinJs, - "ui/lib/angular-route.min.js": uiLibAngularRouteMinJs, - "ui/lib/angular-sanitize.min.js": uiLibAngularSanitizeMinJs, - "ui/lib/angular.min.js": uiLibAngularMinJs, - "ui/lib/d3.v3.min.js": uiLibD3V3MinJs, - "ui/lib/jquery.min.js": uiLibJqueryMinJs, - "ui/lib/js-yaml.min.js": uiLibJsYamlMinJs, - "ui/lib/kube.min.css": uiLibKubeMinCss, - "ui/lib/moment.min.js": uiLibMomentMinJs, - "ui/lib/routing-tree.js": uiLibRoutingTreeJs, + "ui/app/partials/silence.html": uiAppPartialsSilenceHtml, + "ui/app/partials/silences.html": uiAppPartialsSilencesHtml, + "ui/app/partials/status.html": uiAppPartialsStatusHtml, + "ui/bindata.go": uiBindataGo, + "ui/lib/angular-moment.min.js": uiLibAngularMomentMinJs, + "ui/lib/angular-resource.min.js": uiLibAngularResourceMinJs, + "ui/lib/angular-route.min.js": uiLibAngularRouteMinJs, + "ui/lib/angular-sanitize.min.js": uiLibAngularSanitizeMinJs, + "ui/lib/angular.min.js": uiLibAngularMinJs, + "ui/lib/d3.v3.min.js": uiLibD3V3MinJs, + "ui/lib/jquery.min.js": uiLibJqueryMinJs, + "ui/lib/js-yaml.min.js": uiLibJsYamlMinJs, + "ui/lib/kube.min.css": uiLibKubeMinCss, + "ui/lib/moment.min.js": uiLibMomentMinJs, + "ui/lib/routing-tree.js": uiLibRoutingTreeJs, } // AssetDir returns the file names below a certain @@ -644,6 +644,7 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ "ui": &bintree{nil, map[string]*bintree{ "app": &bintree{nil, map[string]*bintree{ @@ -655,28 +656,28 @@ var _bintree = &bintree{nil, map[string]*bintree{ "app.js": &bintree{uiAppJsAppJs, map[string]*bintree{}}, }}, "partials": &bintree{nil, map[string]*bintree{ - "alert.html": &bintree{uiAppPartialsAlertHtml, map[string]*bintree{}}, - "alerts.html": &bintree{uiAppPartialsAlertsHtml, map[string]*bintree{}}, - "route.html": &bintree{uiAppPartialsRouteHtml, map[string]*bintree{}}, + "alert.html": &bintree{uiAppPartialsAlertHtml, map[string]*bintree{}}, + "alerts.html": &bintree{uiAppPartialsAlertsHtml, map[string]*bintree{}}, + "route.html": &bintree{uiAppPartialsRouteHtml, map[string]*bintree{}}, "silence-form.html": &bintree{uiAppPartialsSilenceFormHtml, map[string]*bintree{}}, - "silence.html": &bintree{uiAppPartialsSilenceHtml, map[string]*bintree{}}, - "silences.html": &bintree{uiAppPartialsSilencesHtml, map[string]*bintree{}}, - "status.html": &bintree{uiAppPartialsStatusHtml, map[string]*bintree{}}, + "silence.html": &bintree{uiAppPartialsSilenceHtml, map[string]*bintree{}}, + "silences.html": &bintree{uiAppPartialsSilencesHtml, map[string]*bintree{}}, + "status.html": &bintree{uiAppPartialsStatusHtml, map[string]*bintree{}}, }}, }}, "bindata.go": &bintree{uiBindataGo, map[string]*bintree{}}, "lib": &bintree{nil, map[string]*bintree{ - "angular-moment.min.js": &bintree{uiLibAngularMomentMinJs, map[string]*bintree{}}, + "angular-moment.min.js": &bintree{uiLibAngularMomentMinJs, map[string]*bintree{}}, "angular-resource.min.js": &bintree{uiLibAngularResourceMinJs, map[string]*bintree{}}, - "angular-route.min.js": &bintree{uiLibAngularRouteMinJs, map[string]*bintree{}}, + "angular-route.min.js": &bintree{uiLibAngularRouteMinJs, map[string]*bintree{}}, "angular-sanitize.min.js": &bintree{uiLibAngularSanitizeMinJs, map[string]*bintree{}}, - "angular.min.js": &bintree{uiLibAngularMinJs, map[string]*bintree{}}, - "d3.v3.min.js": &bintree{uiLibD3V3MinJs, map[string]*bintree{}}, - "jquery.min.js": &bintree{uiLibJqueryMinJs, map[string]*bintree{}}, - "js-yaml.min.js": &bintree{uiLibJsYamlMinJs, map[string]*bintree{}}, - "kube.min.css": &bintree{uiLibKubeMinCss, map[string]*bintree{}}, - "moment.min.js": &bintree{uiLibMomentMinJs, map[string]*bintree{}}, - "routing-tree.js": &bintree{uiLibRoutingTreeJs, map[string]*bintree{}}, + "angular.min.js": &bintree{uiLibAngularMinJs, map[string]*bintree{}}, + "d3.v3.min.js": &bintree{uiLibD3V3MinJs, map[string]*bintree{}}, + "jquery.min.js": &bintree{uiLibJqueryMinJs, map[string]*bintree{}}, + "js-yaml.min.js": &bintree{uiLibJsYamlMinJs, map[string]*bintree{}}, + "kube.min.css": &bintree{uiLibKubeMinCss, map[string]*bintree{}}, + "moment.min.js": &bintree{uiLibMomentMinJs, map[string]*bintree{}}, + "routing-tree.js": &bintree{uiLibRoutingTreeJs, map[string]*bintree{}}, }}, }}, }} @@ -727,4 +728,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } -