github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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  	"sync"
     8  
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/instance"
    12  	"github.com/juju/juju/network"
    13  )
    14  
    15  type apiHostPortsSetter interface {
    16  	SetAPIHostPorts([][]network.HostPort) error
    17  }
    18  
    19  type publisher struct {
    20  	st apiHostPortsSetter
    21  
    22  	mu             sync.Mutex
    23  	lastAPIServers [][]network.HostPort
    24  }
    25  
    26  func newPublisher(st apiHostPortsSetter) *publisher {
    27  	return &publisher{st: st}
    28  }
    29  
    30  func (pub *publisher) publishAPIServers(apiServers [][]network.HostPort, instanceIds []instance.Id) error {
    31  	if len(apiServers) == 0 {
    32  		return errors.Errorf("no api servers specified")
    33  	}
    34  	pub.mu.Lock()
    35  	defer pub.mu.Unlock()
    36  
    37  	sortedAPIServers := make([][]network.HostPort, len(apiServers))
    38  	for i, hostPorts := range apiServers {
    39  		sortedAPIServers[i] = append([]network.HostPort{}, hostPorts...)
    40  		network.SortHostPorts(sortedAPIServers[i])
    41  	}
    42  	if apiServersEqual(sortedAPIServers, pub.lastAPIServers) {
    43  		logger.Debugf("API host ports have not changed")
    44  		return nil
    45  	}
    46  
    47  	// TODO(rog) publish instanceIds in environment storage.
    48  	err := pub.st.SetAPIHostPorts(sortedAPIServers)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	pub.lastAPIServers = sortedAPIServers
    53  	return nil
    54  }
    55  
    56  func apiServersEqual(a, b [][]network.HostPort) bool {
    57  	if len(a) != len(b) {
    58  		return false
    59  	}
    60  	for i, hostPortsA := range a {
    61  		hostPortsB := b[i]
    62  		if len(hostPortsA) != len(hostPortsB) {
    63  			return false
    64  		}
    65  		for j := range hostPortsA {
    66  			if hostPortsA[j] != hostPortsB[j] {
    67  				return false
    68  			}
    69  		}
    70  	}
    71  	return true
    72  }