or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aop.mdconfiguration.mddependency-injection.mdfunctions.mdhttp-client.mdhttp-server.mdindex.mdmanagement.mdmessaging.mdreactive.mdretry.mdscheduling.mdwebsocket.md

retry.mddocs/

0

# Retry and Circuit Breaker

1

2

Micronaut provides comprehensive resilience patterns including retry logic, circuit breakers, and bulkhead isolation to handle failures and improve application reliability.

3

4

## Capabilities

5

6

### Retry Logic

7

8

Automatically retry failed operations with configurable strategies.

9

10

```java { .api }

11

/**

12

* Retry configuration and usage

13

*/

14

@Singleton

15

public class ExternalService {

16

17

@Retryable(attempts = "3", delay = "1s")

18

public String callExternal() {

19

// Method will be retried up to 3 times with 1 second delay

20

return restClient.getData();

21

}

22

23

@Retryable(attempts = "5", delay = "2s", multiplier = "2")

24

public String callWithBackoff() {

25

// Exponential backoff: 2s, 4s, 8s, 16s

26

return restClient.getData();

27

}

28

29

@Retryable(

30

attempts = "3",

31

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

32

excludes = {IllegalArgumentException.class}

33

)

34

public String callWithSpecificExceptions() {

35

// Only retry on specific exceptions

36

return restClient.getData();

37

}

38

39

@Retryable(attempts = "3", delay = "1s")

40

Single<String> reactiveRetry() {

41

// Reactive retry support

42

return Single.fromCallable(() -> restClient.getData());

43

}

44

}

45

```

46

47

### Circuit Breaker

48

49

Protect against cascading failures with circuit breaker patterns.

50

51

```java { .api }

52

/**

53

* Circuit breaker configuration

54

*/

55

@Singleton

56

public class ReliableService {

57

58

@CircuitBreaker

59

public String reliableCall() {

60

// Default circuit breaker configuration

61

return externalService.call();

62

}

63

64

@CircuitBreaker(

65

attempts = "5",

66

openTimeout = "30s",

67

resetTimeout = "60s"

68

)

69

public String configuredCircuitBreaker() {

70

// Custom circuit breaker settings

71

return externalService.call();

72

}

73

74

@CircuitBreaker(includes = {ConnectException.class})

75

@Fallback

76

public String circuitBreakerWithFallback() {

77

// Circuit breaker with fallback method

78

return externalService.call();

79

}

80

81

// Fallback method for circuitBreakerWithFallback

82

public String circuitBreakerWithFallback(CircuitOpenException ex) {

83

return "Service temporarily unavailable";

84

}

85

}

86

```

87

88

### Bulkhead Pattern

89

90

Isolate different parts of the application to prevent resource exhaustion.

91

92

```java { .api }

93

/**

94

* Bulkhead isolation

95

*/

96

@Singleton

97

public class IsolatedService {

98

99

@Bulkhead(value = "critical-operations", maxConcurrency = 10)

100

public String criticalOperation() {

101

// Limited to 10 concurrent executions

102

return performCriticalWork();

103

}

104

105

@Bulkhead(value = "background-tasks", maxConcurrency = 5, maxWaitDuration = "5s")

106

public CompletableFuture<String> backgroundTask() {

107

// Background tasks with wait timeout

108

return CompletableFuture.supplyAsync(this::performBackgroundWork);

109

}

110

}

111

```

112

113

### Timeout Protection

114

115

Add timeout protection to prevent operations from hanging indefinitely.

116

117

```java { .api }

118

/**

119

* Timeout configuration

120

*/

121

@Singleton

122

public class TimedService {

123

124

@TimedOut("5s")

125

public String timedOperation() {

126

// Operation will timeout after 5 seconds

127

return longRunningOperation();

128

}

129

130

@TimedOut("10s")

131

@Fallback

132

public String timedOperationWithFallback() {

133

// Timeout with fallback

134

return longRunningOperation();

135

}

136

137

// Fallback method for timeout

138

public String timedOperationWithFallback(TimeoutException ex) {

139

return "Operation timed out, using cached result";

140

}

141

142

@TimedOut("3s")

143

Single<String> reactiveTimeout() {

144

// Reactive timeout support

145

return Single.fromCallable(this::longRunningOperation);

146

}

147

}

148

```

149

150

### Combined Resilience Patterns

151

152

Combine multiple resilience patterns for comprehensive protection.

153

154

```java { .api }

155

/**

156

* Combined resilience patterns

157

*/

158

@Singleton

159

public class ResilientService {

160

161

@Retryable(attempts = "3", delay = "1s")

162

@CircuitBreaker(attempts = "5", openTimeout = "30s")

163

@TimedOut("10s")

164

@Fallback

165

public String resilientOperation() {

166

// Combined retry, circuit breaker, timeout, and fallback

167

return externalService.call();

168

}

169

170

// Fallback for resilientOperation

171

public String resilientOperation(Exception ex) {

172

if (ex instanceof CircuitOpenException) {

173

return "Circuit breaker is open";

174

} else if (ex instanceof TimeoutException) {

175

return "Operation timed out";

176

} else {

177

return "Operation failed after retries";

178

}

179

}

180

181

@Bulkhead("api-calls")

182

@Retryable(attempts = "2")

183

@CircuitBreaker

184

Publisher<String> resilientReactiveOperation() {

185

// Reactive resilience patterns

186

return Flowable.fromCallable(() -> externalService.call());

187

}

188

}

189

```

190

191

### Configuration

192

193

Configure resilience patterns through application properties.

194

195

```java { .api }

196

/**

197

* Resilience configuration properties

198

*/

199

@ConfigurationProperties("resilience")

200

public class ResilienceConfiguration {

201

202

@ConfigurationProperties("retry")

203

public static class RetryConfiguration {

204

private int attempts = 3;

205

private Duration delay = Duration.ofSeconds(1);

206

private double multiplier = 1.0;

207

208

// getters and setters

209

}

210

211

@ConfigurationProperties("circuit-breaker")

212

public static class CircuitBreakerConfiguration {

213

private int attempts = 5;

214

private Duration openTimeout = Duration.ofSeconds(30);

215

private Duration resetTimeout = Duration.ofMinutes(1);

216

217

// getters and setters

218

}

219

220

@ConfigurationProperties("bulkhead")

221

public static class BulkheadConfiguration {

222

private int maxConcurrency = 10;

223

private Duration maxWaitDuration = Duration.ofSeconds(5);

224

225

// getters and setters

226

}

227

}

228

```

229

230

## Types

231

232

```java { .api }

233

// Resilience annotations

234

@Target({ElementType.METHOD})

235

@Retention(RetentionPolicy.RUNTIME)

236

public @interface Retryable {

237

String attempts() default "3";

238

String delay() default "1s";

239

String multiplier() default "1.0";

240

Class<? extends Throwable>[] includes() default {};

241

Class<? extends Throwable>[] excludes() default {};

242

}

243

244

@Target({ElementType.METHOD})

245

@Retention(RetentionPolicy.RUNTIME)

246

public @interface CircuitBreaker {

247

String attempts() default "20";

248

String openTimeout() default "20s";

249

String resetTimeout() default "20s";

250

Class<? extends Throwable>[] includes() default {};

251

Class<? extends Throwable>[] excludes() default {};

252

double failureThreshold() default 0.5;

253

}

254

255

@Target({ElementType.METHOD})

256

@Retention(RetentionPolicy.RUNTIME)

257

public @interface Bulkhead {

258

String value() default "";

259

int maxConcurrency() default 10;

260

String maxWaitDuration() default "0s";

261

}

262

263

@Target({ElementType.METHOD})

264

@Retention(RetentionPolicy.RUNTIME)

265

public @interface TimedOut {

266

String value();

267

}

268

269

@Target({ElementType.METHOD})

270

@Retention(RetentionPolicy.RUNTIME)

271

public @interface Fallback {

272

}

273

274

// Exception types

275

public class CircuitOpenException extends RuntimeException {

276

public CircuitOpenException(String message);

277

public CircuitOpenException(String message, Throwable cause);

278

}

279

280

public class BulkheadRejectionException extends RuntimeException {

281

public BulkheadRejectionException(String message);

282

public BulkheadRejectionException(String message, Throwable cause);

283

}

284

285

// Circuit breaker states

286

public enum CircuitState {

287

CLOSED, OPEN, HALF_OPEN

288

}

289

290

// Retry context

291

public interface RetryContext {

292

int getCurrentAttempt();

293

int getMaxAttempts();

294

Duration getDelay();

295

Throwable getLastException();

296

}

297

```