Parcourir la source

Comment the poller

Brendan Abolivier il y a 6 ans
Parent
révision
046788a748
Signé par: Brendan Abolivier <contact@brendanabolivier.com> ID de la clé GPG: 8EF1500759F70623
1 fichiers modifiés avec 55 ajouts et 0 suppressions
  1. 55
    0
      src/pusher/poller/poller.go

+ 55
- 0
src/pusher/poller/poller.go Voir le fichier

@@ -12,12 +12,18 @@ import (
12 12
 	"github.com/sirupsen/logrus"
13 13
 )
14 14
 
15
+// Setup loads (and synchronise if needed) the Git repository mentioned in the
16
+// configuration file, then creates the poller that will pull from the Git
17
+// repository on a regular basis and push all the changes to Grafana.
18
+// Returns an error if the poller encountered one.
15 19
 func Setup(cfg *config.Config, client *grafana.Client, delRemoved bool) error {
20
+	// Load the Git repository.
16 21
 	r, needsSync, err := git.NewRepository(cfg.Git)
17 22
 	if err != nil {
18 23
 		return err
19 24
 	}
20 25
 
26
+	// Synchronise the repository if needed.
21 27
 	if needsSync {
22 28
 		if err = r.Sync(false); err != nil {
23 29
 			return err
@@ -26,6 +32,8 @@ func Setup(cfg *config.Config, client *grafana.Client, delRemoved bool) error {
26 32
 
27 33
 	errs := make(chan error, 1)
28 34
 
35
+	// In the future we may want to poll from several Git repositories, so we
36
+	// run the poller in a go routine.
29 37
 	go func() {
30 38
 		if err = poller(cfg, r, client, delRemoved); err != nil {
31 39
 			errs <- err
@@ -37,10 +45,23 @@ func Setup(cfg *config.Config, client *grafana.Client, delRemoved bool) error {
37 45
 	return err
38 46
 }
39 47
 
48
+// poller gets the current status of the Git repository that has previously been
49
+// loaded, and then starts an infinite loop that will pull from the Git
50
+// remote, then, if there was any new commit, retrieve the contents of the
51
+// modified and added files to push them to Grafana. If set by the user via
52
+// a command-line flag, it will also check for removed files and delete the
53
+// corresponding dashboards from Grafana. It then sleeps for the time specified
54
+// in the configuration file, before starting its next iteration.
55
+// Returns an error if there was an issue checking the Git repository status,
56
+// synchronising it, reading the files' contents or discussing with the Grafana
57
+// API
40 58
 func poller(
41 59
 	cfg *config.Config, repo *git.Repository, client *grafana.Client,
42 60
 	delRemoved bool,
43 61
 ) (err error) {
62
+	// Get current state of the repo.
63
+	// This is mainly to give an initial value to variables that will see their
64
+	// content changed with every iteration of the loop.
44 65
 	latestCommit, err := repo.GetLatestCommit()
45 66
 	if err != nil {
46 67
 		return
@@ -51,38 +72,58 @@ func poller(
51 72
 		return
52 73
 	}
53 74
 
75
+	// We'll need to know the previous commit in order to compare its hash with
76
+	// the one from the most recent commit after we pull from the remote, se we
77
+	// know if there was any new commit.
54 78
 	previousCommit := latestCommit
79
+	// We need to store the content of the files from the previous iteration of
80
+	// the loop in order to manage removed files which contents won't be
81
+	// accessible anymore.
55 82
 	previousFilesContents := filesContents
56 83
 
84
+	// Start looping
57 85
 	for {
86
+		// Synchronise the repository (i.e. pull from remote).
58 87
 		if err = repo.Sync(true); err != nil {
59 88
 			return
60 89
 		}
61 90
 
91
+		// Retrieve the latest commit in order to compare its hash with the
92
+		// previous one.
62 93
 		latestCommit, err = repo.GetLatestCommit()
63 94
 		if err != nil {
64 95
 			return
65 96
 		}
66 97
 
98
+		// If there is at least one new commit, handle the changes it introduces.
67 99
 		if previousCommit.Hash.String() != latestCommit.Hash.String() {
68 100
 			logrus.WithFields(logrus.Fields{
69 101
 				"previous_hash": previousCommit.Hash.String(),
70 102
 				"new_hash":      latestCommit.Hash.String(),
71 103
 			}).Info("New commit(s) detected")
72 104
 
105
+			// Get the updated files contents.
73 106
 			filesContents, err = repo.GetFilesContentsAtCommit(latestCommit)
74 107
 			if err != nil {
75 108
 				return err
76 109
 			}
77 110
 
111
+			// Get the name of the files that have been added/modified and
112
+			// removed between the two iterations.
78 113
 			modified, removed, err := repo.GetModifiedAndRemovedFiles(previousCommit, latestCommit)
79 114
 			if err != nil {
80 115
 				return err
81 116
 			}
82 117
 
118
+			// Get a map containing the latest known content of each added,
119
+			// modified and removed file.
83 120
 			mergedContents := mergeContents(modified, removed, filesContents, previousFilesContents)
121
+			// Push the contents of the files that were added or modified to the
122
+			// Grafana API.
84 123
 			common.PushFiles(modified, mergedContents, client)
85 124
 
125
+			// If the user requested it, delete all dashboards that were removed
126
+			// from the repository.
86 127
 			if delRemoved {
87 128
 				common.DeleteDashboards(removed, mergedContents, client)
88 129
 			}
@@ -99,22 +140,36 @@ func poller(
99 140
 			}
100 141
 		}
101 142
 
143
+		// Update the commit and files contents to prepare for the next iteration.
102 144
 		previousCommit = latestCommit
103 145
 		previousFilesContents = filesContents
146
+
147
+		// Sleep before the next iteration.
104 148
 		time.Sleep(time.Duration(cfg.Pusher.Config.Interval) * time.Second)
105 149
 	}
106 150
 }
107 151
 
152
+// mergeContents will take as arguments a list of names of files that have been
153
+// added/modified, a list of names of files that have been removed from the Git
154
+// repository, the current contents of the files in the Git repository, and the
155
+// contents of the files in the Git repository as they were at the previous
156
+// iteration of the poller's loop.
157
+// It will create and return a map contaning the current content of all
158
+// added/modified file, and the previous content of all removed file (since
159
+// they are no longer accessible on disk). All files in this map is either added,
160
+// modified or removed on the Git repository.
108 161
 func mergeContents(
109 162
 	modified []string, removed []string,
110 163
 	filesContents map[string][]byte, previousFilesContents map[string][]byte,
111 164
 ) (merged map[string][]byte) {
112 165
 	merged = make(map[string][]byte)
113 166
 
167
+	// Load the added/modified files' contents
114 168
 	for _, modifiedFile := range modified {
115 169
 		merged[modifiedFile] = filesContents[modifiedFile]
116 170
 	}
117 171
 
172
+	// Load the removed files' contents
118 173
 	for _, removedFile := range removed {
119 174
 		merged[removedFile] = previousFilesContents[removedFile]
120 175
 	}