diff --git a/app.go b/app.go index 351441d097a92d5d3febdc6ceebbf9e68ce51776..66621ee69da5baf7f88b3fed69a6a112749e12c5 100644 --- a/app.go +++ b/app.go @@ -94,6 +94,9 @@ func (a *theApp) UpdateDomains(domains domains) { func (a *theApp) Run() { var wg sync.WaitGroup + lastUpdate := []byte("first-update") + updateDomains(a.Domain, a.UpdateDomains, &lastUpdate) + // Listen for HTTP for _, fd := range a.ListenHTTP { wg.Add(1) @@ -143,8 +146,7 @@ func (a *theApp) Run() { } }(a.ListenMetrics) } - - go watchDomains(a.Domain, a.UpdateDomains, time.Second) + go watchDomains(a.Domain, a.UpdateDomains, time.Second, &lastUpdate) wg.Wait() } diff --git a/domains.go b/domains.go index d298b63b65590f72cddcbf2b290be8ee6b700b62..78f13ccfd9a5030ee1f7ed2cd87d89c0a18a69c2 100644 --- a/domains.go +++ b/domains.go @@ -124,38 +124,39 @@ func (d domains) ReadGroups(rootDomain string) error { return nil } -func watchDomains(rootDomain string, updater domainsUpdater, interval time.Duration) { - lastUpdate := []byte("no-update") - +// We should block other goroutines until the first update has been completed +func watchDomains(rootDomain string, updater domainsUpdater, interval time.Duration, lastUpdate *[]byte) { for { - // Read the update file - update, err := ioutil.ReadFile(".update") - if err != nil && !os.IsNotExist(err) { - log.Println("Failed to read update timestamp:", err) - } + time.Sleep(interval) + updateDomains(rootDomain, updater, lastUpdate) + } +} - // If it's the same ignore - if bytes.Equal(lastUpdate, update) { - time.Sleep(interval) - continue - } - lastUpdate = update +func updateDomains(rootDomain string, updater domainsUpdater, lastUpdate *[]byte) { + // Read the update file + update, err := ioutil.ReadFile(".update") + if err != nil && !os.IsNotExist(err) { + log.Println("Failed to read update timestamp:", err) + } - started := time.Now() - domains := make(domains) - domains.ReadGroups(rootDomain) - duration := time.Since(started) - log.Println("Updated", len(domains), "domains in", duration, "Hash:", update) + if bytes.Equal(*lastUpdate, update) { + return + } - if updater != nil { - updater(domains) - } + *lastUpdate = update - // Update prometheus metrics - metrics.DomainLastUpdateTime.Set(float64(time.Now().UTC().Unix())) - metrics.DomainsServed.Set(float64(len(domains))) - metrics.DomainUpdates.Inc() + started := time.Now() + domains := make(domains) + domains.ReadGroups(rootDomain) + duration := time.Since(started) + log.Println("Updated", len(domains), "domains in", duration, "Hash:", update) - time.Sleep(interval) + if updater != nil { + updater(domains) } + + // Update prometheus metrics + metrics.DomainLastUpdateTime.Set(float64(time.Now().UTC().Unix())) + metrics.DomainsServed.Set(float64(len(domains))) + metrics.DomainUpdates.Inc() } diff --git a/domains_test.go b/domains_test.go index 5a2882d692c6d084ff0153658805887ed520324b..8feb1f73bbc048dab489bf5430d9e58b309e6746 100644 --- a/domains_test.go +++ b/domains_test.go @@ -52,9 +52,10 @@ func TestWatchDomains(t *testing.T) { setUpTests() update := make(chan domains) + lastUpdate := []byte("no-update") go watchDomains("gitlab.io", func(domains domains) { update <- domains - }, time.Microsecond*50) + }, time.Microsecond*50, &lastUpdate) defer os.Remove(updateFile) diff --git a/helpers_test.go b/helpers_test.go index 60d04304514732703b30d729c0911c957e5d1e78..559f6fe33eb3917e8e09dfbab56ebe7190ff0cd2 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -47,6 +47,7 @@ var InsecureHTTPSClient = &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, + Timeout: 10 * time.Second, } var CertificateFixture = `-----BEGIN CERTIFICATE----- @@ -153,11 +154,9 @@ func RunPagesProcess(t *testing.T, pagesPath string, listeners []ListenSpec, pro // for now. Without it, intermittent failures occur. // // TODO: replace this with explicit status from the pages binary - // TODO: fix the first-request race for _, spec := range listeners { spec.WaitUntilListening() } - time.Sleep(500 * time.Millisecond) return func() { cmd.Process.Signal(os.Interrupt)