示例#1
0
func (client *Client) initBalancer() *balancer.Balancer {
	dialers := make([]*balancer.Dialer, 0, len(client.cfg.Client.FrontedServers))

	for _, s := range client.cfg.Client.FrontedServers {
		dialer := (&s).dialer()
		dialers = append(dialers, dialer)
	}

	bal := balancer.New(dialers...)

	if client.balInitialized {
		log.Printf("Draining balancer channel.")
		old := <-client.balCh
		// Close old balancer on a goroutine to avoid blocking here
		go func() {
			old.Close()
			log.Printf("Closed old balancer.")
		}()
	} else {
		log.Printf("Creating balancer channel.")
		client.balCh = make(chan *balancer.Balancer, 1)
	}

	log.Printf("Publishing balancer.")

	client.balInitialized = true
	client.balCh <- bal

	return bal
}
示例#2
0
// initBalancer takes hosts from cfg.FrontedServers and cfg.ChainedServers and
// it uses them to create a balancer. It also looks for the highest QOS dialer
// available among the fronted servers.
func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, fronted.Dialer) {
	var highestQOSFrontedDialer fronted.Dialer

	// The dialers slice must be large enough to handle all fronted and chained
	// servers.
	dialers := make([]*balancer.Dialer, 0, len(cfg.FrontedServers)+len(cfg.ChainedServers))

	// Add fronted servers.
	log.Debugf("Adding %d domain fronted servers", len(cfg.FrontedServers))
	highestQOS := math.MinInt32
	for _, s := range cfg.FrontedServers {
		// Get a dialer for domain fronting (fd) and a dialer to dial to arbitrary
		// addreses (dialer).
		fd, dialer := s.dialer(cfg.MasqueradeSets)
		dialers = append(dialers, dialer)
		if dialer.QOS > highestQOS {
			// If this dialer as a higher QOS than our current highestQOS, set it as
			// the highestQOSFrontedDialer.
			highestQOSFrontedDialer = fd
			highestQOS = dialer.QOS
		}
	}

	// Add chained (CONNECT proxy) servers.
	log.Debugf("Adding %d chained servers", len(cfg.ChainedServers))
	for _, s := range cfg.ChainedServers {
		dialer, err := s.Dialer()
		if err == nil {
			dialers = append(dialers, dialer)
		} else {
			log.Errorf("Unable to configure chained server. Received error: %v", err)
		}
	}

	bal := balancer.New(dialers...)

	if client.balInitialized {
		log.Trace("Draining balancer channel")
		old := <-client.balCh
		// Close old balancer on a goroutine to avoid blocking here
		go func() {
			old.Close()
			log.Debug("Closed old balancer")
		}()
	} else {
		log.Trace("Creating balancer channel")
		client.balCh = make(chan *balancer.Balancer, 1)
	}

	log.Trace("Publishing balancer")

	client.balCh <- bal

	// We don't need to protect client.balInitialized from race conditions
	// because it's only accessed here in initBalancer, which always gets called
	// under Configure, which never gets called concurrently with itself.
	client.balInitialized = true

	return bal, highestQOSFrontedDialer
}
示例#3
0
// initBalancer takes hosts from cfg.ChainedServers and it uses them to create a
// balancer.
func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, error) {
	if len(cfg.ChainedServers) == 0 {
		return nil, fmt.Errorf("No chained servers configured, not initializing balancer")
	}
	// The dialers slice must be large enough to handle all chained
	// servers.
	dialers := make([]*balancer.Dialer, 0, len(cfg.ChainedServers))

	// Add chained (CONNECT proxy) servers.
	log.Debugf("Adding %d chained servers", len(cfg.ChainedServers))
	for _, s := range cfg.ChainedServers {
		dialer, err := s.Dialer(cfg.DeviceID)
		if err == nil {
			dialers = append(dialers, dialer)
		} else {
			log.Errorf("Unable to configure chained server. Received error: %v", err)
		}
	}

	bal := balancer.New(dialers...)
	var oldBal *balancer.Balancer
	var ok bool
	ob, ok := client.bal.Get(0 * time.Millisecond)
	if ok {
		oldBal = ob.(*balancer.Balancer)
	}

	log.Trace("Publishing balancer")
	client.bal.Set(bal)

	if oldBal != nil {
		// Close old balancer on a goroutine to avoid blocking here
		go func() {
			oldBal.Close()
			log.Debug("Closed old balancer")
		}()
	}

	return bal, nil
}