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

programmatic-api.mddocs/

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

```