gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

retry-continous.go (1973B)


      1 /*
      2  * MinIO Go Library for Amazon S3 Compatible Cloud Storage
      3  * Copyright 2015-2017 MinIO, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package minio
     19 
     20 import "time"
     21 
     22 // newRetryTimerContinous creates a timer with exponentially increasing delays forever.
     23 func (c *Client) newRetryTimerContinous(unit time.Duration, cap time.Duration, jitter float64, doneCh chan struct{}) <-chan int {
     24 	attemptCh := make(chan int)
     25 
     26 	// normalize jitter to the range [0, 1.0]
     27 	if jitter < NoJitter {
     28 		jitter = NoJitter
     29 	}
     30 	if jitter > MaxJitter {
     31 		jitter = MaxJitter
     32 	}
     33 
     34 	// computes the exponential backoff duration according to
     35 	// https://www.awsarchitectureblog.com/2015/03/backoff.html
     36 	exponentialBackoffWait := func(attempt int) time.Duration {
     37 		// 1<<uint(attempt) below could overflow, so limit the value of attempt
     38 		maxAttempt := 30
     39 		if attempt > maxAttempt {
     40 			attempt = maxAttempt
     41 		}
     42 		// sleep = random_between(0, min(cap, base * 2 ** attempt))
     43 		sleep := unit * time.Duration(1<<uint(attempt))
     44 		if sleep > cap {
     45 			sleep = cap
     46 		}
     47 		if jitter != NoJitter {
     48 			sleep -= time.Duration(c.random.Float64() * float64(sleep) * jitter)
     49 		}
     50 		return sleep
     51 	}
     52 
     53 	go func() {
     54 		defer close(attemptCh)
     55 		var nextBackoff int
     56 		for {
     57 			select {
     58 			// Attempts starts.
     59 			case attemptCh <- nextBackoff:
     60 				nextBackoff++
     61 			case <-doneCh:
     62 				// Stop the routine.
     63 				return
     64 			}
     65 			time.Sleep(exponentialBackoffWait(nextBackoff))
     66 		}
     67 	}()
     68 	return attemptCh
     69 }