| 
									
										
										
										
											2015-10-13 12:27:50 +02:00
										 |  |  | package retry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	RetryFailed = errors.New("All retry attempts failed.") | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type RetryStrategy interface { | 
					
						
							|  |  |  | 	On(func() error) error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type retryer struct { | 
					
						
							|  |  |  | 	NextDelay func(int) int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *retryer) On(method func() error) error { | 
					
						
							|  |  |  | 	attempt := 0 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		err := method() | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		delay := r.NextDelay(attempt) | 
					
						
							|  |  |  | 		if delay < 0 { | 
					
						
							|  |  |  | 			return RetryFailed | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		<-time.After(time.Duration(delay) * time.Millisecond) | 
					
						
							| 
									
										
										
										
											2015-10-14 00:57:00 +02:00
										 |  |  | 		attempt++ | 
					
						
							| 
									
										
										
										
											2015-10-13 12:27:50 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Timed(attempts int, delay int) RetryStrategy { | 
					
						
							|  |  |  | 	return &retryer{ | 
					
						
							|  |  |  | 		NextDelay: func(attempt int) int { | 
					
						
							|  |  |  | 			if attempt >= attempts { | 
					
						
							|  |  |  | 				return -1 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return delay | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |