This repository has been archived by the owner on Aug 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
simple.go
133 lines (111 loc) · 3.66 KB
/
simple.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package pollster
import (
"context"
"time"
"github.com/coinbase/watchdog/config"
"github.com/coinbase/watchdog/primitives/datadog/client"
"github.com/coinbase/watchdog/primitives/datadog/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// NewSimplePollster returns an instance of a simple polling scheduler.
func NewSimplePollster(client *client.Client, interval time.Duration, cfg *config.Config, componentFn func(component types.Component, team, project string, id int) bool) Pollster {
return &simplePoller{
interval: interval,
cfg: cfg,
ca: newComponentAccessors(client),
componentAllowed: componentFn,
}
}
type simplePoller struct {
ca *componentAccessors
interval time.Duration
cfg *config.Config
componentAllowed func(component types.Component, team, project string, id int) bool
}
func newComponentAccessors(c *client.Client) *componentAccessors {
return &componentAccessors{
getDashboards: c.GetDashboards,
getMonitors: c.GetMonitors,
getScreenBoards: c.GetScreenboards,
}
}
// ComponentAccessors is a structure contains functions to query datadog to get a list of components.
type componentAccessors struct {
getDashboards func() (client.DashboardsResponse, error)
getMonitors func() (client.MonitorsResponse, error)
getScreenBoards func() (client.ScreenBoardsResponse, error)
}
// Do in implementation of pollster interface.
func (s *simplePoller) Do(ctx context.Context) chan *Response {
result := make(chan *Response)
go s.start(ctx, result)
return result
}
func (s *simplePoller) start(ctx context.Context, result chan *Response) {
ticker := time.Tick(s.interval)
logrus.Infof("Start polling with interval %s", s.interval)
for {
select {
case <-ctx.Done():
logrus.Warn("Shutting down pollster")
return
case <-ticker:
logrus.Debug("Start polling datadog for changes")
s.poll(result)
}
}
}
func (s *simplePoller) poll(result chan *Response) {
for component, pollFn := range map[types.Component]func() ([]int, error){
types.ComponentDashboard: s.pollDashboards,
types.ComponentMonitor: s.pollMonitors,
types.ComponentScreenboard: s.pollScreenBoards,
} {
ids, err := pollFn()
if err != nil {
logrus.Error(err)
continue
}
s.sendFilteredResponse(component, ids, result)
}
}
func (s *simplePoller) pollDashboards() ([]int, error) {
dashboards, err := s.ca.getDashboards()
if err != nil {
return nil, errors.Wrap(err, "unable to get dashboards")
}
return dashboards.GetModifiedIDsWithin(s.interval, nil)
}
func (s *simplePoller) pollMonitors() ([]int, error) {
monitors, err := s.ca.getMonitors()
if err != nil {
return nil, errors.Wrap(err, "unable to get monitors")
}
return monitors.GetModifiedIDsWithin(s.interval, nil)
}
func (s *simplePoller) pollScreenBoards() ([]int, error) {
screenBoards, err := s.ca.getScreenBoards()
if err != nil {
return nil, errors.Wrap(err, "unable to get screenboards")
}
return screenBoards.GetModifiedIDsWithin(s.interval, nil)
}
func (s *simplePoller) sendFilteredResponse(component types.Component, ids []int, result chan *Response) {
for _, id := range ids {
userConfigFiles := s.cfg.UserConfigFilesByComponentID(component, id)
// send one event per user file
for _, userConfigFile := range userConfigFiles {
logrus.Debugf("Detected a change %s id %d", component, id)
if s.componentAllowed != nil && !s.componentAllowed(component, userConfigFile.Meta.Team, userConfigFile.Meta.Project, id) {
logrus.Debugf("Change is not allowed. Skipping")
continue
}
result <- &Response{
UserConfigFile: userConfigFile,
Component: component,
ID: id,
}
}
}
}