/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 9 . ĠOpen L attice , ĠInc . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġfree Ġsoftware : Ġyou Ġcan Ġredistribute Ġit Ġand / or Ġmodify Ċ Ġ* Ġit Ġunder Ġthe Ġterms Ġof Ġthe ĠGNU ĠGeneral ĠPublic ĠLicense Ġas Ġpublished Ġby Ċ Ġ* Ġthe ĠFree ĠSoftware ĠFoundation , Ġeither Ġversion Ġ 3 Ġof Ġthe ĠLicense , Ġor Ċ Ġ* Ġ( at Ġyour Ġoption ) Ġany Ġlater Ġversion . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġdistributed Ġin Ġthe Ġhope Ġthat Ġit Ġwill Ġbe Ġuseful , Ċ Ġ* Ġbut ĠWITHOUT ĠANY ĠWARRANTY ; Ġwithout Ġeven Ġthe Ġimplied Ġwarranty Ġof Ċ Ġ* ĠMERCHANTABILITY Ġor ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE . Ġ ĠSee Ġthe Ċ Ġ* ĠGNU ĠGeneral ĠPublic ĠLicense Ġfor Ġmore Ġdetails . Ċ Ġ* Ċ Ġ* ĠYou Ġshould Ġhave Ġreceived Ġa Ġcopy Ġof Ġthe ĠGNU ĠGeneral ĠPublic ĠLicense Ċ Ġ* Ġalong Ġwith Ġthis Ġprogram . Ġ ĠIf Ġnot , Ġsee Ġ< http :// www . gnu . org / licenses />. Ċ Ġ* Ċ Ġ* ĠYou Ġcan Ġcontact Ġthe Ġowner Ġof Ġthe Ġcopyright Ġat Ġsupport @ open l attice . com Ċ Ġ* Ċ Ġ* Ċ Ġ*/ Ċ Ċ package Ġcom . ge ek be ast . util Ċ Ċ import Ġorg . apache . commons . lang 3 . Random Utils Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ import Ġkotlin . math . sqrt Ċ Ċ /** Ċ Ġ* Ċ Ġ* Ġ@ author ĠMat thew ĠT am ay o - R ios Ġ& lt ; mat thew @ open l attice . com & gt ; Ċ Ġ*/ Ċ class ĠRetry able Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ċ } Ċ Ċ class ĠRetry able Call FailedException Ġ: ĠRuntimeException Ġ{ ĊĠĠĠ Ġconstructor ( message : ĠString ) Ġ: Ġsuper ( message ) ĊĠĠĠ Ġconstructor ( message : ĠString , Ġcause : ĠThrowable ) Ġ: Ġsuper ( message , Ġcause ) Ċ } Ċ Ċ open Ġclass ĠRetry Strategy ( val Ġstrategy : Ġ( Long ) Ġ-> ĠLong , Ġprivate Ġvar Ġcurrent Delay Millis : ĠLong Ġ= Ġ 1 0 0 0 L ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠLoggerFactory . getLogger ( this . java Class ) ĊĊĠĠĠ Ġfun Ġbackoff () Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Delay Millis Ġ= Ġstrategy ( current Delay Millis ) ĊĠĠĠĠĠĠĠ Ġlogger . info (" Waiting Ġ$ current Delay Millis Ġto Ġretry Ġupload .") ĊĠĠĠĠĠĠĠ ĠThread . sleep ( current Delay Millis ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ inline Ġfun Ġ< T , ĠR > ĠT . attempt ( retry Strategy : ĠRetry Strategy , Ġmax Attempts : ĠInt , Ġblock : ĠT . () Ġ-> ĠR ): ĠR Ġ{ ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. max Attempts ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġblock () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogger Ġ= ĠLoggerFactory . getLogger (( this Ġ?: ĠRetry able ):: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" Error Ġoccured Ġperforming Ġretry able Ġoperation Ġduring Ġattempt Ġ$ i .", Ġex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġretry Strategy . backoff () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġthrow ĠRetry able Call FailedException (" Reached Ġmax Ġnumber Ġof Ġretry Ġattempts Ġ($ max Attempts )") Ċ } ĊĊ Ċ open Ġclass ĠExp onent ial Backoff Ġ@ Jvm Over loads Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmax Interval : ĠLong , ĊĠĠĠĠĠĠĠ Ġmin Ratio : ĠDouble Ġ= Ġ 1 . 5 , ĊĠĠĠĠĠĠĠ Ġmax Ratio : ĠDouble Ġ= Ġ 2 . 5 , ĊĠĠĠĠĠĠĠ Ġinitial Delay Millis : ĠLong Ġ= Ġ 1 0 0 0 L Ċ ) Ġ: ĠRetry Strategy ( ĊĠĠĠĠĠĠĠ Ġ{ Ġcurrent Interval Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmin ( max Interval , Ġ( Random Utils . next Double ( min Ratio , Ġmax Ratio ) Ġ* Ġcurrent Interval ). to Long ()) ĊĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġinitial Delay Millis Ċ ) Ċ Ċ open Ġclass ĠQu adr atic Backoff ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmax Interval : ĠLong Ċ ) Ġ: ĠRetry Strategy ( ĊĠĠĠĠĠĠĠ Ġ{ Ġcurrent Interval Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Interval , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( current Interval Ġ+ ĠRandom Utils . next Long ( 1 , Ġ 1 0 0 ) Ġ+ Ġ 2 Ġ* Ġsqrt ( current Interval . toDouble ()). to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ċ ) Ċ Ċ open Ġclass ĠLinear Backoff ( ĊĠĠĠĠĠĠĠ Ġval Ġmax Interval : ĠLong , ĊĠĠĠĠĠĠĠ Ġval Ġoffset : ĠLong Ċ ) Ġ: ĠRetry Strategy ( ĊĠĠĠĠĠĠĠ Ġ{ Ġcurrent Interval Ġ-> Ġmax ( max Interval , Ġcurrent Interval Ġ+ ĠRandom Utils . next Long ( 1 , Ġ 1 0 0 ) Ġ+ Ġoffset ) Ġ} Ċ ) Ċ