func (r *randomBalancer) writeServiceToCache(serviceName string) ([]*balancer.ServiceLocation, error) {
	//acquire a write lock
	r.cacheLock.Lock()
	defer r.cacheLock.Unlock()

	//check the cache again in case we've fetched since the last check
	//(our lock could have been waiting for another call to this function)
	if result, ok := r.cache[serviceName]; ok {
		if time.Now().UTC().Before(result.CachedAt.Add(r.ttl)) {
			return result.Services, nil
		}
	}

	//it still isn't in the cache, lets put it there
	consulServices, _, err := r.consulCatalog.Service(serviceName, r.environment, true, nil)
	if err != nil {
		return nil, fmt.Errorf("Error reaching consul for service lookup %v", err)
	}

	if len(consulServices) == 0 {
		return nil, fmt.Errorf("No services found for %s", serviceName)
	}

	//setup service locations
	var services []*balancer.ServiceLocation
	for _, v := range consulServices {
		s := &balancer.ServiceLocation{}
		s.URL = v.Service.Address
		s.Port = v.Service.Port
		services = append(services, s)
	}

	// cache
	c := cachedServiceLocation{Services: services, CachedAt: time.Now().UTC()}
	r.cache[serviceName] = c
	return services, nil
}
func (r *randomBalancer) writeServiceToCache(serviceName string) ([]*balancer.ServiceLocation, error) {
	
	r.cacheLock.Lock()
	defer r.cacheLock.Unlock()

	
	
	if result, ok := r.cache[serviceName]; ok {
		if time.Now().UTC().Before(result.CachedAt.Add(r.ttl)) {
			return result.Services, nil
		}
	}

	
	consulServices, _, err := r.consulCatalog.Service(serviceName, r.environment, true, nil)
	if err != nil {
		return nil, fmt.Errorf("Error reaching consul for service lookup %v", err)
	}

	if len(consulServices) == 0 {
		return nil, fmt.Errorf("No services found for %s", serviceName)
	}

	
	var services []*balancer.ServiceLocation
	for _, v := range consulServices {
		s := &balancer.ServiceLocation{}
		s.URL = v.Service.Address
		s.Port = v.Service.Port
		services = append(services, s)
	}

	
	c := cachedServiceLocation{Services: services, CachedAt: time.Now().UTC()}
	r.cache[serviceName] = c
	return services, nil
}
func ( r * randomBalancer ) writeServiceToCache ( serviceName string ) ( [ ] * balancer . ServiceLocation , error ) { //acquire a write lock r . cacheLock . Lock ( ) defer r . cacheLock . Unlock ( ) //check the cache again in case we've fetched since the last check //(our lock could have been waiting for another call to this function) if result , ok := r . cache [ serviceName ] ; ok { if time . Now ( ) . UTC ( ) . Before ( result . CachedAt . Add ( r . ttl ) ) { return result . Services , nil } } //it still isn't in the cache, lets put it there consulServices , _ , err := r . consulCatalog . Service ( serviceName , r . environment , true , nil ) if err != nil { return nil , fmt . Errorf ( " " , err ) } if len ( consulServices ) == 0 { return nil , fmt . Errorf ( " " , serviceName ) } //setup service locations var services [ ] * balancer . ServiceLocation for _ , v := range consulServices { s := & balancer . ServiceLocation { } s . URL = v . Service . Address s . Port = v . Service . Port services = append ( services , s ) } // cache c := cachedServiceLocation { Services : services , CachedAt : time . Now ( ) . UTC ( ) } r . cache [ serviceName ] = c return services , nil }
// writeServiceToCache locks specifically to alleviate load on consul some additional lock time
// is preferable to extra consul calls
writeServiceToCache locks specifically to alleviate load on consul some additional lock time is preferable to extra consul calls