...

Source file src/github.com/ory/x/resilience/retry.go

Documentation: github.com/ory/x/resilience

     1  /*
     2   * Copyright © 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   * @author		Aeneas Rekkas <aeneas+oss@aeneas.io>
    17   * @copyright 	2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
    18   * @license 	Apache-2.0
    19   */
    20  
    21  // Package resilience provides helpers for dealing with resilience.
    22  package resilience
    23  
    24  import (
    25  	"time"
    26  
    27  	"github.com/pkg/errors"
    28  
    29  	"github.com/ory/x/logrusx"
    30  )
    31  
    32  // Retry executes a f until no error is returned or failAfter is reached.
    33  func Retry(logger *logrusx.Logger, maxWait time.Duration, failAfter time.Duration, f func() error) (err error) {
    34  	var lastStart time.Time
    35  	err = errors.New("did not connect")
    36  	loopWait := time.Millisecond * 100
    37  	retryStart := time.Now().UTC()
    38  	for retryStart.Add(failAfter).After(time.Now().UTC()) {
    39  		lastStart = time.Now().UTC()
    40  		if err = f(); err == nil {
    41  			return nil
    42  		}
    43  
    44  		if lastStart.Add(maxWait * 2).Before(time.Now().UTC()) {
    45  			retryStart = time.Now().UTC()
    46  		}
    47  
    48  		logger.WithError(err).Infof("Retrying in %f seconds...", loopWait.Seconds())
    49  		time.Sleep(loopWait)
    50  		loopWait = loopWait * time.Duration(int64(2))
    51  		if loopWait > maxWait {
    52  			loopWait = maxWait
    53  		}
    54  	}
    55  	return err
    56  }
    57  

View as plain text