Refactored main and some error messages

This commit is contained in:
Ian Lewis 2018-10-22 12:43:40 +09:00
parent ba9379dfb8
commit 7755300638
3 changed files with 24 additions and 27 deletions

View File

@ -36,7 +36,7 @@ import (
)
// VERSION is the current version of the application.
var VERSION = "0.1.4"
var VERSION = "0.1.5"
// Domain is a single domain listed in the configuration file.
type Domain struct {
@ -113,7 +113,7 @@ func getConfig(pathToJSON string) (Config, error) {
}
// Main is the main function for the cloud-dyndns-client command. It returns the OS exit code.
func Main() int {
func main() {
addr := flag.String("addr", ":8080", "Address to listen on for health checks.")
version := flag.Bool("version", false, "Print the version and exit.")
config := flag.String("config", "/etc/cloud-dyndns-client/config.json", "The path to the JSON config file.")
@ -122,12 +122,12 @@ func Main() int {
if *version {
fmt.Println(VERSION)
return 0
return
}
cfg, err := getConfig(*config)
if err != nil {
log.Fatalf("Error reading config: %#v", err)
log.Fatalf("Error reading config: %v", err)
}
// Convert config to sync records
@ -160,6 +160,7 @@ func Main() int {
ctx, cancel := context.WithCancel(context.Background())
wg, ctx := errgroup.WithContext(ctx)
// TODO: Refactor and move this code to it's own package
wg.Go(func() error { return syncer.Run(ctx.Done()) })
wg.Go(func() error { return poller.Run(ctx.Done()) })
wg.Go(func() error {
@ -182,6 +183,7 @@ func Main() int {
}
}
})
// TODO: Refactor and move to it's own package
wg.Go(func() error {
// This goroutine sets up health checks on an HTTP endpoint.
// It's a bit complicated as it is necessary to gracefully
@ -221,19 +223,13 @@ func Main() int {
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
select {
case s := <-signals:
log.Printf("Received signal %#v, exiting...", s)
log.Printf("Received signal %v, exiting...", s)
case <-ctx.Done():
}
cancel()
if err := wg.Wait(); err != nil {
log.Printf("Unhandled error received. Exiting: %s %#v", err.Error(), err)
return 1
log.Fatalf("Unhandled error received. Exiting: %v", err)
os.Exit(1)
}
return 0
}
func main() {
os.Exit(Main())
}

View File

@ -83,7 +83,7 @@ func (p *IPAddressPoller) poll() error {
return nil
}
return fmt.Errorf("Could not obtain IP address: %s %#v", lastErr.Error(), lastErr)
return fmt.Errorf("Could not obtain IP address: %v", lastErr)
}
// request() makes a request to a URL to get the internet IP address.
@ -102,7 +102,7 @@ func request(url string) (string, error) {
return "", err
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("Got status code from %s: %s", url, resp.StatusCode)
return "", fmt.Errorf("Got status code from %q: %d", url, resp.StatusCode)
}
z := html.NewTokenizer(resp.Body)
@ -122,24 +122,21 @@ func request(url string) (string, error) {
}
}
}
return "", fmt.Errorf("Could not obtain IP address from html body")
}
// Run() starts the main loop for the poller.
func (i *IPAddressPoller) Run(stopCh <-chan struct{}) error {
if err := i.poll(); err != nil {
log.Printf("Error polling for IP: %s %#v", err.Error(), err)
log.Printf("Error polling for IP: %v", err)
}
for {
select {
case <-time.After(i.pollInterval):
if err := i.poll(); err != nil {
log.Printf("Error polling for IP: %s %#v", err.Error(), err)
log.Printf("Error polling for IP: %v", err)
}
case <-stopCh:
return nil
}
}
return nil
}

View File

@ -112,10 +112,10 @@ func (s *Syncer) UpdateRecord(dnsName, dnsType string, ttl int64, data []string)
return fmt.Errorf("Domain %s not registered.", dnsName)
}
// needsUpdate() returns true if the first DNSRecord needs to be
// updated with the remote backend as compared to the remote
// version of the DNSRecord.
func needsUpdate(l backend.DNSRecord, r backend.DNSRecord) bool {
// needsUpdate() compares the left/local DNSRecord against the right/remote
// DNSRecord and returns true if the record needs to be updated in the remote
// backend.
func needsUpdate(l, r backend.DNSRecord) bool {
if l == nil {
return false
}
@ -175,14 +175,16 @@ func (s *Syncer) pollSingle(d *domainObj) error {
// poll() runs a loop to poll the backend and update the remote cache.
func (s *Syncer) poll(d *domainObj, stopCh <-chan struct{}) {
// Start by polling the domain to initialize the remote value and local cache
// TODO: Implement some exponential retry backoff logic in case poll interval is long
if err := s.pollSingle(d); err != nil {
log.Printf("Error polling DNS record %s %#v %#v %s", err.Error(), d, err)
log.Printf("Error polling DNS record %q: %v", d.managed.Name(), err)
}
for {
select {
case <-time.After(s.pollInterval):
if err := s.pollSingle(d); err != nil {
log.Printf("Error polling DNS record: %s %#v %#v", err.Error(), d, err)
log.Printf("Error polling DNS record %q: %v", d.managed.Name(), err)
}
case <-stopCh:
return
@ -210,7 +212,7 @@ func (s *Syncer) syncSingle(d *domainObj) error {
if d.remote != nil {
deletions = []backend.DNSRecord{d.remote}
}
log.Printf("Updating record: %#v", d.managed)
log.Printf("Updating record %v", d.managed.Name())
err := d.backend.UpdateRecords(ctx, additions, deletions)
if err != nil {
return err
@ -246,6 +248,8 @@ func (s *Syncer) sync(d *domainObj, stopCh <-chan struct{}) {
// Run() starts the sync and poll loops
func (s *Syncer) Run(stopCh <-chan struct{}) error {
// Run a sync and poll loop for each domain. Sync and poll loops are
// separated so that polling and syncing do not block on each other.
for _, d := range s.domains {
go s.poll(d, stopCh)
go s.sync(d, stopCh)