0
# Programmatic API
1
2
Programmatic fault tolerance configuration using TypedGuard and Guard interfaces for scenarios where annotation-based configuration is insufficient or dynamic configuration is required.
3
4
## Capabilities
5
6
### TypedGuard Creation
7
8
Create typed guards for specific return types with fluent configuration API.
9
10
```java { .api }
11
TypedGuard<ReturnType> guard = TypedGuard.create(ReturnType.class)
12
.withRetry().maxRetries(3).delay(1000, ChronoUnit.MILLISECONDS).done()
13
.withCircuitBreaker().requestVolumeThreshold(10).failureRatio(0.5).done()
14
.withTimeout().timeout(5000, ChronoUnit.MILLISECONDS).done()
15
.build();
16
17
// Guard usage
18
ReturnType result = guard.call(() -> riskyOperation());
19
```
20
21
#### Usage Example
22
23
```java
24
@ApplicationScoped
25
public class ProgrammaticFaultToleranceService {
26
27
private final Supplier<String> weatherSupplier;
28
private final Function<String, WeatherData> weatherFunction;
29
30
@PostConstruct
31
public void initializeGuards() {
32
// Create guard for weather API calls
33
TypedGuard<String> weatherGuard = TypedGuard.create(String.class)
34
.withRetry()
35
.maxRetries(3)
36
.delay(1000, ChronoUnit.MILLISECONDS)
37
.retryOn(IOException.class, TimeoutException.class)
38
.done()
39
.withCircuitBreaker()
40
.requestVolumeThreshold(10)
41
.failureRatio(0.4)
42
.delay(30000, ChronoUnit.MILLISECONDS)
43
.done()
44
.withTimeout()
45
.timeout(8000, ChronoUnit.MILLISECONDS)
46
.done()
47
.build();
48
49
// Adapt supplier for easy usage
50
weatherSupplier = weatherGuard.adaptSupplier(() -> {
51
return weatherApiClient.getCurrentWeather();
52
});
53
54
// Create function guard for city-specific weather
55
TypedGuard<WeatherData> cityWeatherGuard = TypedGuard.create(WeatherData.class)
56
.withRetry()
57
.maxRetries(2)
58
.delay(500, ChronoUnit.MILLISECONDS)
59
.done()
60
.withCircuitBreaker()
61
.requestVolumeThreshold(5)
62
.failureRatio(0.3)
63
.name("city-weather-circuit")
64
.done()
65
.build();
66
67
weatherFunction = cityWeatherGuard.adaptFunction(city -> {
68
return weatherApiClient.getWeatherForCity(city);
69
});
70
}
71
72
public String getCurrentWeather() {
73
return weatherSupplier.get();
74
}
75
76
public WeatherData getWeatherForCity(String city) {
77
return weatherFunction.apply(city);
78
}
79
}
80
```
81
82
### Guard Configuration Options
83
84
Comprehensive configuration options for all fault tolerance strategies.
85
86
#### Retry Configuration
87
88
```java { .api }
89
TypedGuard<T> guard = TypedGuard.create(ReturnType.class)
90
.withRetry()
91
.maxRetries(5)
92
.delay(1000, ChronoUnit.MILLISECONDS)
93
.maxDuration(30000, ChronoUnit.MILLISECONDS)
94
.jitter(200, ChronoUnit.MILLISECONDS)
95
.retryOn(IOException.class, TimeoutException.class)
96
.abortOn(SecurityException.class)
97
.done()
98
.build();
99
```
100
101
#### Circuit Breaker Configuration
102
103
```java { .api }
104
TypedGuard<T> guard = TypedGuard.create(ReturnType.class)
105
.withCircuitBreaker()
106
.requestVolumeThreshold(20)
107
.failureRatio(0.5)
108
.delay(10000, ChronoUnit.MILLISECONDS)
109
.successThreshold(3)
110
.name("my-circuit-breaker")
111
.failOn(RuntimeException.class)
112
.skipOn(IllegalArgumentException.class)
113
.done()
114
.build();
115
```
116
117
#### Timeout Configuration
118
119
```java { .api }
120
TypedGuard<T> guard = TypedGuard.create(ReturnType.class)
121
.withTimeout()
122
.timeout(5000, ChronoUnit.MILLISECONDS)
123
.done()
124
.build();
125
```
126
127
#### Bulkhead Configuration
128
129
```java { .api }
130
TypedGuard<T> guard = TypedGuard.create(ReturnType.class)
131
.withBulkhead()
132
.limit(10)
133
.queueSize(20)
134
.done()
135
.build();
136
```
137
138
#### Rate Limit Configuration
139
140
```java { .api }
141
TypedGuard<T> guard = TypedGuard.create(ReturnType.class)
142
.withRateLimit()
143
.limit(100)
144
.window(1, ChronoUnit.MINUTES)
145
.minSpacing(100, ChronoUnit.MILLISECONDS)
146
.type(RateLimitType.ROLLING)
147
.done()
148
.build();
149
```
150
151
### Guard Adaptation Methods
152
153
Different ways to use guards with various functional interfaces.
154
155
```java { .api }
156
// Supplier adaptation (no parameters)
157
Supplier<T> guardedSupplier = guard.adaptSupplier(originalSupplier);
158
159
// Function adaptation (single parameter)
160
Function<P, T> guardedFunction = guard.adaptFunction(originalFunction);
161
162
// Callable adaptation (throws exceptions)
163
T result = guard.call(callableOperation);
164
165
// Runnable adaptation (void return)
166
guard.run(runnableOperation);
167
```
168
169
#### Usage Example
170
171
```java
172
@ApplicationScoped
173
public class AdaptedGuardService {
174
175
private final Supplier<List<User>> userListSupplier;
176
private final Function<Long, User> userByIdFunction;
177
private final Function<UserQuery, List<User>> userQueryFunction;
178
179
@PostConstruct
180
public void setupGuards() {
181
// Guard for listing all users
182
TypedGuard<List<User>> listGuard = TypedGuard.create(new TypeToken<List<User>>() {})
183
.withRetry().maxRetries(2).delay(500, ChronoUnit.MILLISECONDS).done()
184
.withTimeout().timeout(3000, ChronoUnit.MILLISECONDS).done()
185
.build();
186
187
userListSupplier = listGuard.adaptSupplier(() -> {
188
return userRepository.findAll();
189
});
190
191
// Guard for finding user by ID
192
TypedGuard<User> userGuard = TypedGuard.create(User.class)
193
.withRetry().maxRetries(3).done()
194
.withCircuitBreaker().requestVolumeThreshold(10).done()
195
.build();
196
197
userByIdFunction = userGuard.adaptFunction(userId -> {
198
return userRepository.findById(userId);
199
});
200
201
// Guard for complex queries
202
TypedGuard<List<User>> queryGuard = TypedGuard.create(new TypeToken<List<User>>() {})
203
.withBulkhead().limit(5).done()
204
.withTimeout().timeout(10000, ChronoUnit.MILLISECONDS).done()
205
.build();
206
207
userQueryFunction = queryGuard.adaptFunction(query -> {
208
return userRepository.find(query);
209
});
210
}
211
212
public List<User> getAllUsers() {
213
return userListSupplier.get();
214
}
215
216
public User findUserById(Long userId) {
217
return userByIdFunction.apply(userId);
218
}
219
220
public List<User> findUsers(UserQuery query) {
221
return userQueryFunction.apply(query);
222
}
223
}
224
```
225
226
### Dynamic Guard Configuration
227
228
Runtime configuration of guards based on external parameters or conditions.
229
230
```java { .api }
231
public TypedGuard<T> createDynamicGuard(GuardConfiguration config) {
232
TypedGuardBuilder<T> builder = TypedGuard.create(ReturnType.class);
233
234
if (config.isRetryEnabled()) {
235
builder = builder.withRetry()
236
.maxRetries(config.getMaxRetries())
237
.delay(config.getRetryDelay(), ChronoUnit.MILLISECONDS)
238
.done();
239
}
240
241
if (config.isCircuitBreakerEnabled()) {
242
builder = builder.withCircuitBreaker()
243
.requestVolumeThreshold(config.getCircuitBreakerThreshold())
244
.failureRatio(config.getFailureRatio())
245
.done();
246
}
247
248
return builder.build();
249
}
250
```
251
252
#### Usage Example
253
254
```java
255
@ApplicationScoped
256
public class DynamicGuardService {
257
258
@Inject
259
ConfigurationService configService;
260
261
private Map<String, TypedGuard<ApiResponse>> apiGuards = new ConcurrentHashMap<>();
262
263
public ApiResponse callApi(String apiName, ApiRequest request) {
264
TypedGuard<ApiResponse> guard = getOrCreateGuard(apiName);
265
return guard.call(() -> apiClient.call(apiName, request));
266
}
267
268
private TypedGuard<ApiResponse> getOrCreateGuard(String apiName) {
269
return apiGuards.computeIfAbsent(apiName, name -> {
270
ApiConfiguration config = configService.getApiConfiguration(name);
271
272
TypedGuardBuilder<ApiResponse> builder = TypedGuard.create(ApiResponse.class);
273
274
// Configure retry based on API characteristics
275
builder = builder.withRetry()
276
.maxRetries(config.getMaxRetries())
277
.delay(config.getRetryDelay(), ChronoUnit.MILLISECONDS);
278
279
if (config.hasExponentialBackoff()) {
280
builder = builder.withExponentialBackoff()
281
.factor(config.getBackoffFactor())
282
.maxDelay(config.getMaxBackoffDelay(), ChronoUnit.MILLISECONDS);
283
}
284
285
builder = builder.done();
286
287
// Configure circuit breaker for unreliable APIs
288
if (config.isUnreliable()) {
289
builder = builder.withCircuitBreaker()
290
.requestVolumeThreshold(config.getCircuitThreshold())
291
.failureRatio(config.getFailureRatio())
292
.delay(config.getCircuitDelay(), ChronoUnit.MILLISECONDS)
293
.name(name + "-circuit")
294
.done();
295
}
296
297
// Configure rate limiting for rate-limited APIs
298
if (config.hasRateLimit()) {
299
builder = builder.withRateLimit()
300
.limit(config.getRateLimit())
301
.window(config.getRateWindow(), ChronoUnit.MINUTES)
302
.done();
303
}
304
305
return builder.build();
306
});
307
}
308
}
309
```
310
311
### Guard Composition and Reuse
312
313
Combining multiple guards and reusing guard configurations.
314
315
```java { .api }
316
// Base guard configuration
317
TypedGuard<T> baseGuard = TypedGuard.create(ReturnType.class)
318
.withRetry().maxRetries(3).done()
319
.withTimeout().timeout(5000, ChronoUnit.MILLISECONDS).done()
320
.build();
321
322
// Extended guard with additional strategies
323
TypedGuard<T> extendedGuard = TypedGuard.create(ReturnType.class)
324
.from(baseGuard) // Copy configuration from base guard
325
.withCircuitBreaker().requestVolumeThreshold(10).done()
326
.build();
327
```
328
329
#### Usage Example
330
331
```java
332
@ApplicationScoped
333
public class GuardCompositionService {
334
335
// Base guard for all database operations
336
private final TypedGuard<Object> databaseBaseGuard;
337
338
// Specialized guards for different operation types
339
private final TypedGuard<List<Entity>> queryGuard;
340
private final TypedGuard<Entity> crudGuard;
341
private final TypedGuard<Void> batchOperationGuard;
342
343
@PostConstruct
344
public void initializeGuards() {
345
// Base configuration for all database operations
346
databaseBaseGuard = TypedGuard.create(Object.class)
347
.withRetry()
348
.maxRetries(3)
349
.delay(500, ChronoUnit.MILLISECONDS)
350
.retryOn(SQLException.class, TransientDataAccessException.class)
351
.done()
352
.withTimeout()
353
.timeout(10000, ChronoUnit.MILLISECONDS)
354
.done()
355
.build();
356
357
// Query operations with additional circuit breaker
358
queryGuard = TypedGuard.create(new TypeToken<List<Entity>>() {})
359
.from(databaseBaseGuard)
360
.withCircuitBreaker()
361
.requestVolumeThreshold(15)
362
.failureRatio(0.4)
363
.name("database-query-circuit")
364
.done()
365
.build();
366
367
// CRUD operations with bulkhead
368
crudGuard = TypedGuard.create(Entity.class)
369
.from(databaseBaseGuard)
370
.withBulkhead()
371
.limit(5)
372
.queueSize(10)
373
.done()
374
.build();
375
376
// Batch operations with extended timeout and rate limiting
377
batchOperationGuard = TypedGuard.create(Void.class)
378
.from(databaseBaseGuard)
379
.withTimeout()
380
.timeout(60000, ChronoUnit.MILLISECONDS) // Override base timeout
381
.done()
382
.withRateLimit()
383
.limit(5)
384
.window(1, ChronoUnit.MINUTES)
385
.done()
386
.build();
387
}
388
389
public List<Entity> findEntities(EntityQuery query) {
390
return queryGuard.call(() -> entityRepository.find(query));
391
}
392
393
public Entity saveEntity(Entity entity) {
394
return crudGuard.call(() -> entityRepository.save(entity));
395
}
396
397
public void processBatch(List<Entity> entities) {
398
batchOperationGuard.run(() -> batchProcessor.process(entities));
399
}
400
}
401
```
402
403
## Types
404
405
### Programmatic API Core Types
406
407
```java { .api }
408
// Main typed guard interface
409
interface TypedGuard<T> {
410
T call(Callable<T> callable) throws Exception;
411
void run(Runnable runnable);
412
Supplier<T> adaptSupplier(Supplier<T> supplier);
413
<P> Function<P, T> adaptFunction(Function<P, T> function);
414
<P1, P2> BiFunction<P1, P2, T> adaptBiFunction(BiFunction<P1, P2, T> function);
415
}
416
417
// Builder for typed guards
418
interface TypedGuardBuilder<T> {
419
RetryBuilder<T> withRetry();
420
CircuitBreakerBuilder<T> withCircuitBreaker();
421
TimeoutBuilder<T> withTimeout();
422
BulkheadBuilder<T> withBulkhead();
423
RateLimitBuilder<T> withRateLimit();
424
TypedGuardBuilder<T> from(TypedGuard<?> baseGuard);
425
TypedGuard<T> build();
426
}
427
428
// Guard creation factory
429
class TypedGuard {
430
static <T> TypedGuardBuilder<T> create(Class<T> type);
431
static <T> TypedGuardBuilder<T> create(TypeToken<T> typeToken);
432
}
433
```
434
435
### Strategy Builder Types
436
437
```java { .api }
438
// Retry configuration builder
439
interface RetryBuilder<T> {
440
RetryBuilder<T> maxRetries(int maxRetries);
441
RetryBuilder<T> delay(long delay, ChronoUnit unit);
442
RetryBuilder<T> maxDuration(long maxDuration, ChronoUnit unit);
443
RetryBuilder<T> jitter(long jitter, ChronoUnit unit);
444
RetryBuilder<T> retryOn(Class<? extends Throwable>... exceptions);
445
RetryBuilder<T> abortOn(Class<? extends Throwable>... exceptions);
446
RetryBuilder<T> withExponentialBackoff();
447
RetryBuilder<T> withFibonacciBackoff();
448
RetryBuilder<T> withCustomBackoff(Class<? extends CustomBackoffStrategy> strategy);
449
TypedGuardBuilder<T> done();
450
}
451
452
// Circuit breaker configuration builder
453
interface CircuitBreakerBuilder<T> {
454
CircuitBreakerBuilder<T> requestVolumeThreshold(int threshold);
455
CircuitBreakerBuilder<T> failureRatio(double ratio);
456
CircuitBreakerBuilder<T> delay(long delay, ChronoUnit unit);
457
CircuitBreakerBuilder<T> successThreshold(int threshold);
458
CircuitBreakerBuilder<T> name(String name);
459
CircuitBreakerBuilder<T> failOn(Class<? extends Throwable>... exceptions);
460
CircuitBreakerBuilder<T> skipOn(Class<? extends Throwable>... exceptions);
461
TypedGuardBuilder<T> done();
462
}
463
464
// Additional builder interfaces for other strategies...
465
```
466
467
### Type Token Support
468
469
```java { .api }
470
// Type token for generic type support
471
abstract class TypeToken<T> {
472
protected TypeToken() {}
473
474
public static <T> TypeToken<T> of(Class<T> type);
475
public Type getType();
476
}
477
478
// Usage for generic types
479
TypedGuard<List<String>> listGuard = TypedGuard.create(new TypeToken<List<String>>() {});
480
TypedGuard<Map<String, User>> mapGuard = TypedGuard.create(new TypeToken<Map<String, User>>() {});
481
```