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 }