github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/peergrouper/publish.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package peergrouper
     5  
     6  import (
     7  	"reflect"
     8  	"sync"
     9  
    10  	"github.com/juju/errors"
    11  
    12  	"github.com/juju/juju/network"
    13  )
    14  
    15  // CachingAPIHostPortsSetter is an APIHostPortsSetter that caches the
    16  // most recently set values, suppressing further calls to the underlying
    17  // setter if any call's arguments match those of the preceding call.
    18  type CachingAPIHostPortsSetter struct {
    19  	APIHostPortsSetter
    20  
    21  	mu   sync.Mutex
    22  	last [][]network.HostPort
    23  }
    24  
    25  func (s *CachingAPIHostPortsSetter) SetAPIHostPorts(apiServers [][]network.HostPort) error {
    26  	if len(apiServers) == 0 {
    27  		return errors.Errorf("no API servers specified")
    28  	}
    29  
    30  	sorted := make([][]network.HostPort, len(apiServers))
    31  	for i, hostPorts := range apiServers {
    32  		sorted[i] = append([]network.HostPort{}, hostPorts...)
    33  		network.SortHostPorts(sorted[i])
    34  	}
    35  
    36  	s.mu.Lock()
    37  	defer s.mu.Unlock()
    38  	if reflect.DeepEqual(sorted, s.last) {
    39  		logger.Debugf("API host ports have not changed")
    40  		return nil
    41  	}
    42  
    43  	if err := s.APIHostPortsSetter.SetAPIHostPorts(sorted); err != nil {
    44  		return errors.Annotate(err, "setting API host ports")
    45  	}
    46  	s.last = sorted
    47  	return nil
    48  }
    49  
    50  func apiServersEqual(a, b [][]network.HostPort) bool {
    51  	if len(a) != len(b) {
    52  		return false
    53  	}
    54  	for i, hostPortsA := range a {
    55  		hostPortsB := b[i]
    56  		if len(hostPortsA) != len(hostPortsB) {
    57  			return false
    58  		}
    59  		for j := range hostPortsA {
    60  			if hostPortsA[j] != hostPortsB[j] {
    61  				return false
    62  			}
    63  		}
    64  	}
    65  	return true
    66  }