Commit 0f7185e7 authored by David Eads's avatar David Eads

for aggregated apiserver availability, try multiple endpoints in parallel

parent 454666bc
...@@ -242,33 +242,56 @@ func (c *AvailableConditionController) sync(key string) error { ...@@ -242,33 +242,56 @@ func (c *AvailableConditionController) sync(key string) error {
} }
// actually try to hit the discovery endpoint when it isn't local and when we're routing as a service. // actually try to hit the discovery endpoint when it isn't local and when we're routing as a service.
if apiService.Spec.Service != nil && c.serviceResolver != nil { if apiService.Spec.Service != nil && c.serviceResolver != nil {
discoveryURL, err := c.serviceResolver.ResolveEndpoint(apiService.Spec.Service.Namespace, apiService.Spec.Service.Name, apiService.Spec.Service.Port) attempts := 5
if err != nil { results := make(chan error, attempts)
return err for i := 0; i < attempts; i++ {
} go func() {
discoveryURL, err := c.serviceResolver.ResolveEndpoint(apiService.Spec.Service.Namespace, apiService.Spec.Service.Name, apiService.Spec.Service.Port)
if err != nil {
results <- err
return
}
errCh := make(chan error) errCh := make(chan error)
go func() { go func() {
resp, err := c.discoveryClient.Get(discoveryURL.String()) resp, err := c.discoveryClient.Get(discoveryURL.String())
if resp != nil { if resp != nil {
resp.Body.Close() resp.Body.Close()
} }
errCh <- err errCh <- err
}() }()
select {
case err = <-errCh:
if err != nil {
results <- fmt.Errorf("no response from %v: %v", discoveryURL, err)
return
}
// we had trouble with slow dial and DNS responses causing us to wait too long.
// we added this as insurance
case <-time.After(6 * time.Second):
results <- fmt.Errorf("timed out waiting for %v", discoveryURL)
return
}
select { results <- nil
case err = <-errCh: }()
}
// we had trouble with slow dial and DNS responses causing us to wait too long. var lastError error
// we added this as insurance for i := 0; i < attempts; i++ {
case <-time.After(6 * time.Second): lastError = <-results
err = fmt.Errorf("timed out waiting for %v", discoveryURL) // if we had at least one success, we are successful overall and we can return now
if lastError == nil {
break
}
} }
if err != nil { if lastError != nil {
availableCondition.Status = apiregistration.ConditionFalse availableCondition.Status = apiregistration.ConditionFalse
availableCondition.Reason = "FailedDiscoveryCheck" availableCondition.Reason = "FailedDiscoveryCheck"
availableCondition.Message = fmt.Sprintf("no response from %v: %v", discoveryURL, err) availableCondition.Message = lastError.Error()
apiregistration.SetAPIServiceCondition(apiService, availableCondition) apiregistration.SetAPIServiceCondition(apiService, availableCondition)
_, updateErr := updateAPIServiceStatus(c.apiServiceClient, originalAPIService, apiService) _, updateErr := updateAPIServiceStatus(c.apiServiceClient, originalAPIService, apiService)
if updateErr != nil { if updateErr != nil {
...@@ -276,7 +299,7 @@ func (c *AvailableConditionController) sync(key string) error { ...@@ -276,7 +299,7 @@ func (c *AvailableConditionController) sync(key string) error {
} }
// force a requeue to make it very obvious that this will be retried at some point in the future // force a requeue to make it very obvious that this will be retried at some point in the future
// along with other requeues done via service change, endpoint change, and resync // along with other requeues done via service change, endpoint change, and resync
return err return lastError
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment