or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asynchronous-strategies.mdbulkhead-strategies.mdcircuit-breaker-strategies.mdconfiguration.mdfallback-strategies.mdindex.mdprogrammatic-api.mdrate-limiting-strategies.mdretry-strategies.mdtimeout-strategies.md

retry-strategies.mddocs/

0

# Retry Strategies

1

2

Comprehensive retry mechanisms with configurable delays, maximum attempts, and conditional retry logic. Supports standard retry patterns, custom backoff strategies, and predicate-based conditional retries.

3

4

## Capabilities

5

6

### Basic Retry

7

8

Standard retry functionality with configurable maximum attempts, delays, and exception handling.

9

10

```java { .api }

11

@Retry(

12

maxRetries = 3,

13

delay = 1000,

14

delayUnit = ChronoUnit.MILLISECONDS,

15

maxDuration = 30000,

16

durationUnit = ChronoUnit.MILLISECONDS,

17

jitter = 200,

18

jitterDelayUnit = ChronoUnit.MILLISECONDS,

19

retryOn = {IOException.class, TimeoutException.class},

20

abortOn = {SecurityException.class}

21

)

22

public ReturnType retryableMethod() throws Exception;

23

```

24

25

#### Parameters

26

27

- `maxRetries` - Maximum number of retry attempts (default: 3)

28

- `delay` - Delay between retry attempts in specified units (default: 0)

29

- `delayUnit` - Time unit for delay (default: MILLIS)

30

- `maxDuration` - Maximum total time to spend retrying (default: 180000ms)

31

- `durationUnit` - Time unit for max duration (default: MILLIS)

32

- `jitter` - Random jitter added to delays (default: 200ms)

33

- `jitterDelayUnit` - Time unit for jitter (default: MILLIS)

34

- `retryOn` - Exception types that trigger retry (default: Exception.class)

35

- `abortOn` - Exception types that prevent retry (takes precedence over retryOn)

36

37

#### Usage Example

38

39

```java

40

@ApplicationScoped

41

public class ExternalApiService {

42

43

// Basic retry with exponential backoff

44

@Retry(maxRetries = 5, delay = 1000)

45

@ExponentialBackoff(factor = 2, maxDelay = 30000)

46

public String callExternalApi(String endpoint) throws IOException {

47

// Implementation that may fail and should be retried

48

return httpClient.get(endpoint);

49

}

50

51

// Retry with specific exceptions

52

@Retry(

53

maxRetries = 3,

54

retryOn = {SocketTimeoutException.class, ConnectException.class},

55

abortOn = {SecurityException.class, IllegalArgumentException.class}

56

)

57

public ApiResponse secureApiCall(String token, String data) {

58

return authenticatedHttpClient.post(data, token);

59

}

60

}

61

```

62

63

### Conditional Retry

64

65

Advanced retry logic based on exception types, return values, or custom predicates.

66

67

```java { .api }

68

@RetryWhen(

69

exception = ExceptionPredicate.class,

70

result = ResultPredicate.class

71

)

72

public ReturnType conditionalRetryMethod();

73

74

// Predicate interfaces

75

class ExceptionPredicate implements Predicate<Throwable> {

76

public boolean test(Throwable throwable);

77

}

78

79

class ResultPredicate implements Predicate<Object> {

80

public boolean test(Object result);

81

}

82

```

83

84

#### Usage Example

85

86

```java

87

@ApplicationScoped

88

public class DataService {

89

90

// Retry based on custom exception logic

91

@RetryWhen(exception = RetryableHttpExceptionPredicate.class)

92

public ApiData fetchData(String id) {

93

return apiClient.getData(id);

94

}

95

96

// Retry based on return value

97

@RetryWhen(result = IncompleteDataPredicate.class)

98

public DataSet processData(String input) {

99

return dataProcessor.process(input);

100

}

101

}

102

103

// Custom predicates

104

public class RetryableHttpExceptionPredicate implements Predicate<Throwable> {

105

@Override

106

public boolean test(Throwable throwable) {

107

if (throwable instanceof HttpException) {

108

HttpException httpEx = (HttpException) throwable;

109

// Retry on 5xx server errors but not 4xx client errors

110

return httpEx.getStatusCode() >= 500;

111

}

112

return false;

113

}

114

}

115

116

public class IncompleteDataPredicate implements Predicate<Object> {

117

@Override

118

public boolean test(Object result) {

119

if (result instanceof DataSet) {

120

DataSet dataSet = (DataSet) result;

121

// Retry if data set is incomplete

122

return dataSet.isEmpty() || !dataSet.isComplete();

123

}

124

return false;

125

}

126

}

127

```

128

129

### Exponential Backoff

130

131

Exponential delay growth between retry attempts to reduce load on failing systems.

132

133

```java { .api }

134

@ExponentialBackoff(

135

factor = 2,

136

maxDelay = 60000,

137

maxDelayUnit = ChronoUnit.MILLISECONDS

138

)

139

public ReturnType exponentialBackoffMethod();

140

```

141

142

#### Parameters

143

144

- `factor` - Multiplicative factor for delay growth (default: 2)

145

- `maxDelay` - Maximum delay between retries (default: 1 minute)

146

- `maxDelayUnit` - Time unit for max delay (default: MILLIS)

147

148

#### Usage Example

149

150

```java

151

@ApplicationScoped

152

public class DatabaseService {

153

154

// Database retry with exponential backoff

155

@Retry(maxRetries = 5, delay = 500)

156

@ExponentialBackoff(factor = 3, maxDelay = 30000)

157

public QueryResult executeQuery(String sql) throws SQLException {

158

return database.query(sql);

159

}

160

161

// Combined with circuit breaker for resilience

162

@Retry(maxRetries = 3)

163

@ExponentialBackoff()

164

@CircuitBreaker(requestVolumeThreshold = 10)

165

public void performDatabaseUpdate(UpdateQuery query) throws SQLException {

166

database.execute(query);

167

}

168

}

169

```

170

171

### Fibonacci Backoff

172

173

Fibonacci sequence-based delays for more gradual backoff than exponential.

174

175

```java { .api }

176

@FibonacciBackoff(

177

maxDelay = 60000,

178

maxDelayUnit = ChronoUnit.MILLISECONDS

179

)

180

public ReturnType fibonacciBackoffMethod();

181

```

182

183

#### Parameters

184

185

- `maxDelay` - Maximum delay between retries (default: 1 minute)

186

- `maxDelayUnit` - Time unit for max delay (default: MILLIS)

187

188

#### Usage Example

189

190

```java

191

@ApplicationScoped

192

public class MessageService {

193

194

// Message queue retry with Fibonacci backoff

195

@Retry(maxRetries = 8, delay = 100)

196

@FibonacciBackoff(maxDelay = 20000)

197

public void sendMessage(Message message) throws MessagingException {

198

messageQueue.send(message);

199

}

200

}

201

```

202

203

### Custom Backoff

204

205

Custom backoff strategies for specialized retry delay patterns.

206

207

```java { .api }

208

@CustomBackoff(CustomBackoffStrategy.class)

209

public ReturnType customBackoffMethod();

210

211

// Custom backoff strategy interface

212

interface CustomBackoffStrategy {

213

long nextDelayInMillis(int attemptIndex);

214

}

215

```

216

217

#### Usage Example

218

219

```java

220

@ApplicationScoped

221

public class SpecializedService {

222

223

// Custom backoff for API rate limiting

224

@Retry(maxRetries = 10)

225

@CustomBackoff(RateLimitBackoffStrategy.class)

226

public ApiResponse callRateLimitedApi(String endpoint) {

227

return apiClient.get(endpoint);

228

}

229

}

230

231

// Custom backoff implementation

232

public class RateLimitBackoffStrategy implements CustomBackoffStrategy {

233

private static final long[] DELAYS = {1000, 2000, 5000, 10000, 20000};

234

235

@Override

236

public long nextDelayInMillis(int attemptIndex) {

237

if (attemptIndex < DELAYS.length) {

238

return DELAYS[attemptIndex];

239

}

240

// For attempts beyond defined delays, use maximum delay

241

return DELAYS[DELAYS.length - 1];

242

}

243

}

244

```

245

246

### Before Retry Hooks

247

248

Execute custom logic before each retry attempt for logging, cleanup, or state management.

249

250

```java { .api }

251

@BeforeRetry(BeforeRetryHandler.class)

252

public ReturnType beforeRetryMethod();

253

254

// Handler interface

255

interface BeforeRetryHandler {

256

void handle(InvocationContext context);

257

}

258

259

// Alternative: method-based before retry (build-time configuration)

260

@BeforeRetry(methodName = "handleBeforeRetry")

261

public ReturnType methodBasedBeforeRetry();

262

263

public void handleBeforeRetry() {

264

// Custom before retry logic

265

}

266

```

267

268

#### Usage Example

269

270

```java

271

@ApplicationScoped

272

public class MonitoredService {

273

274

@Inject

275

Logger logger;

276

277

@Inject

278

MetricsCollector metrics;

279

280

// Before retry with custom handler

281

@Retry(maxRetries = 3)

282

@BeforeRetry(RetryLoggingHandler.class)

283

public String monitoredApiCall(String endpoint) throws Exception {

284

return externalApi.call(endpoint);

285

}

286

287

// Before retry with method

288

@Retry(maxRetries = 5)

289

@BeforeRetry(methodName = "logRetryAttempt")

290

public void importantOperation() throws Exception {

291

performCriticalTask();

292

}

293

294

public void logRetryAttempt() {

295

logger.warn("Retrying important operation due to failure");

296

metrics.incrementRetryCounter("important-operation");

297

}

298

}

299

300

// Custom before retry handler

301

public class RetryLoggingHandler implements BeforeRetryHandler {

302

@Inject

303

Logger logger;

304

305

@Override

306

public void handle(InvocationContext context) {

307

String methodName = context.getMethod().getName();

308

Throwable failure = context.getFailure();

309

logger.info("Retrying method {} due to {}", methodName, failure.getClass().getSimpleName());

310

}

311

}

312

```

313

314

## Types

315

316

### Core Retry Types

317

318

```java { .api }

319

// Time units for delays and durations

320

enum ChronoUnit {

321

NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, DAYS

322

}

323

324

// Invocation context for before retry handlers

325

interface InvocationContext {

326

Method getMethod();

327

Object[] getParameters();

328

Object getTarget();

329

Throwable getFailure();

330

Map<String, Object> getContextData();

331

}

332

333

// Predicate for conditional retry

334

interface Predicate<T> {

335

boolean test(T t);

336

}

337

```

338

339

### Strategy Implementation Types

340

341

```java { .api }

342

// Custom backoff strategy interface

343

interface CustomBackoffStrategy {

344

/**

345

* Calculate the next delay based on attempt index

346

* @param attemptIndex Zero-based index of the retry attempt

347

* @return Delay in milliseconds before next retry

348

*/

349

long nextDelayInMillis(int attemptIndex);

350

}

351

352

// Before retry handler interface

353

interface BeforeRetryHandler {

354

/**

355

* Handle logic to execute before each retry attempt

356

* @param context Invocation context with method and failure information

357

*/

358

void handle(InvocationContext context);

359

}

360

```