or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mdindex.mdpath-template.mdresource-names.md

core-api.mddocs/

0

# Core API

1

2

The core API provides fundamental asynchronous programming utilities, service lifecycle management, and functional interfaces that form the foundation for Google API client libraries.

3

4

## Capabilities

5

6

### ApiFuture Interface

7

8

A future that supports adding listeners, similar to Guava's `ListenableFuture`. This is the primary async result type used throughout Google API libraries.

9

10

```java { .api }

11

/**

12

* A future that can have listeners added to be called when the computation completes

13

* @param <V> The result type returned by this Future's get method

14

*/

15

interface ApiFuture<V> extends Future<V> {

16

/**

17

* Registers a listener to be run on the given executor

18

* @param listener The listener to run when the computation is complete

19

* @param executor The executor to run the listener in

20

*/

21

void addListener(Runnable listener, Executor executor);

22

}

23

```

24

25

### ApiFutures Utility Class

26

27

Static utility methods for working with `ApiFuture` instances, providing transformation, combination, and creation operations.

28

29

```java { .api }

30

/**

31

* Static utility methods for ApiFuture instances

32

*/

33

class ApiFutures {

34

/**

35

* Registers a callback to be run when the given ApiFuture completes

36

* @param future The future to attach the callback to

37

* @param callback The callback to execute on completion

38

* @param executor The executor to run the callback in

39

*/

40

static <V> void addCallback(

41

ApiFuture<V> future,

42

ApiFutureCallback<? super V> callback,

43

Executor executor

44

);

45

46

/**

47

* Creates an ApiFuture which has its value set immediately upon construction

48

* @param value The value to set

49

* @return A future with the given value

50

*/

51

static <V> ApiFuture<V> immediateFuture(V value);

52

53

/**

54

* Creates an ApiFuture which has an exception set immediately upon construction

55

* @param throwable The exception to set

56

* @return A future with the given exception

57

*/

58

static <V> ApiFuture<V> immediateFailedFuture(Throwable throwable);

59

60

/**

61

* Creates an ApiFuture which is cancelled immediately upon construction

62

* @return A cancelled future

63

*/

64

static <V> ApiFuture<V> immediateCancelledFuture();

65

66

/**

67

* Returns a new ApiFuture whose result is the product of applying the given Function to the result of the given ApiFuture

68

* @param input The future to transform

69

* @param function The function to apply to the input future's result

70

* @param executor The executor to run the transformation in

71

* @return A future with the transformed result

72

*/

73

static <I, O> ApiFuture<O> transform(

74

ApiFuture<? extends I> input,

75

ApiFunction<? super I, ? extends O> function,

76

Executor executor

77

);

78

79

/**

80

* Returns a new ApiFuture whose result is asynchronously derived from the result of the given ApiFuture

81

* @param input The future to transform

82

* @param function The function to apply to the input future's result

83

* @param executor The executor to run the transformation in

84

* @return A future with the transformed result

85

*/

86

static <I, O> ApiFuture<O> transformAsync(

87

ApiFuture<I> input,

88

ApiAsyncFunction<I, O> function,

89

Executor executor

90

);

91

92

/**

93

* Creates an ApiFuture whose result is a list containing the results of the given ApiFutures

94

* @param futures The futures to combine

95

* @return A future containing a list of all results

96

*/

97

static <V> ApiFuture<List<V>> allAsList(

98

Iterable<? extends ApiFuture<? extends V>> futures

99

);

100

101

/**

102

* Returns a new ApiFuture whose result is taken from the given primary input or, if the primary input fails with the given exception type, from the result provided by the fallback

103

* @param input The primary input future

104

* @param exceptionType The exception type to catch

105

* @param callback The fallback function to apply on exception

106

* @param executor The executor to run the fallback in

107

* @return A future with error handling applied

108

*/

109

static <V, X extends Throwable> ApiFuture<V> catching(

110

ApiFuture<? extends V> input,

111

Class<X> exceptionType,

112

ApiFunction<? super X, ? extends V> callback,

113

Executor executor

114

);

115

116

/**

117

* Returns a new ApiFuture whose result is asynchronously taken from the given primary input or, if the primary input fails with the given exception type, from the result provided by the fallback

118

* @param input The primary input future

119

* @param exceptionType The exception type to catch

120

* @param callback The async fallback function to apply on exception

121

* @param executor The executor to run the fallback in

122

* @return A future with async error handling applied

123

*/

124

static <V, X extends Throwable> ApiFuture<V> catchingAsync(

125

ApiFuture<V> input,

126

Class<X> exceptionType,

127

ApiAsyncFunction<X, V> callback,

128

Executor executor

129

);

130

131

/**

132

* Creates an ApiFuture whose result is a list containing the results of the given ApiFutures, in the same order, but where null is returned for failed futures

133

* @param futures The futures to combine

134

* @return A future containing a list with successful results and nulls for failures

135

*/

136

@BetaApi

137

static <V> ApiFuture<List<V>> successfulAsList(

138

Iterable<? extends ApiFuture<? extends V>> futures

139

);

140

}

141

```

142

143

**Usage Examples:**

144

145

```java

146

import com.google.api.core.ApiFuture;

147

import com.google.api.core.ApiFutures;

148

import com.google.common.util.concurrent.MoreExecutors;

149

150

// Create immediate futures

151

ApiFuture<String> completedFuture = ApiFutures.immediateFuture("Hello");

152

ApiFuture<String> failedFuture = ApiFutures.immediateFailedFuture(new RuntimeException("Error"));

153

154

// Transform results

155

ApiFuture<Integer> lengthFuture = ApiFutures.transform(

156

completedFuture,

157

String::length,

158

MoreExecutors.directExecutor()

159

);

160

161

// Handle errors

162

ApiFuture<String> withFallback = ApiFutures.catching(

163

failedFuture,

164

RuntimeException.class,

165

throwable -> "Default value",

166

MoreExecutors.directExecutor()

167

);

168

169

// Combine multiple futures

170

List<ApiFuture<String>> futures = Arrays.asList(

171

ApiFutures.immediateFuture("one"),

172

ApiFutures.immediateFuture("two")

173

);

174

ApiFuture<List<String>> combined = ApiFutures.allAsList(futures);

175

```

176

177

### SettableApiFuture

178

179

An `ApiFuture` whose result can be set programmatically. Useful for bridging callback-based APIs to the future-based programming model.

180

181

```java { .api }

182

/**

183

* An ApiFuture whose result can be set manually

184

* @param <V> The result type

185

*/

186

class SettableApiFuture<V> implements ApiFuture<V> {

187

/**

188

* Creates a new SettableApiFuture that can be completed or cancelled by a later method call

189

* @return A new SettableApiFuture

190

*/

191

static <V> SettableApiFuture<V> create();

192

193

/**

194

* Sets the result of this Future unless this Future has already been cancelled or set

195

* @param value The value to set

196

* @return True if this attempt completed this Future, false if it was already complete

197

*/

198

boolean set(V value);

199

200

/**

201

* Sets the result of this Future to the given exception unless this Future has already been cancelled or set

202

* @param throwable The exception to set

203

* @return True if this attempt completed this Future, false if it was already complete

204

*/

205

boolean setException(Throwable throwable);

206

}

207

```

208

209

**Usage Example:**

210

211

```java

212

import com.google.api.core.SettableApiFuture;

213

214

// Create a settable future

215

SettableApiFuture<String> future = SettableApiFuture.create();

216

217

// Set the result from another thread or callback

218

someAsyncOperation(result -> {

219

if (result.isSuccess()) {

220

future.set(result.getValue());

221

} else {

222

future.setException(result.getException());

223

}

224

});

225

226

// Use the future

227

String result = future.get(); // Blocks until set

228

```

229

230

### Functional Interfaces

231

232

Core functional interfaces for transformations and callbacks in the async programming model.

233

234

```java { .api }

235

/**

236

* A transformation function from one type to another

237

* @param <F> The input type

238

* @param <T> The output type

239

*/

240

@FunctionalInterface

241

interface ApiFunction<F, T> {

242

/**

243

* Applies this function to the given argument

244

* @param input The function argument

245

* @return The function result

246

*/

247

T apply(F input);

248

}

249

250

/**

251

* A transformation function that returns an ApiFuture

252

* @param <I> The input type

253

* @param <O> The output type

254

*/

255

@FunctionalInterface

256

interface ApiAsyncFunction<I, O> {

257

/**

258

* Applies this function to the given argument, returning an ApiFuture

259

* @param input The function argument

260

* @return An ApiFuture containing the function result

261

* @throws Exception If the transformation fails

262

*/

263

ApiFuture<O> apply(I input) throws Exception;

264

}

265

266

/**

267

* A callback to be notified when an ApiFuture completes

268

* @param <V> The result type

269

*/

270

interface ApiFutureCallback<V> {

271

/**

272

* Invoked when a computation fails or is cancelled

273

* @param t The failure cause

274

*/

275

void onFailure(Throwable t);

276

277

/**

278

* Invoked when a computation completes successfully

279

* @param result The computation result

280

*/

281

void onSuccess(V result);

282

}

283

```

284

285

### Service Lifecycle Management

286

287

Interfaces and base classes for managing the lifecycle of long-running services with startup, shutdown, and state monitoring.

288

289

```java { .api }

290

/**

291

* An object with an operational state, asynchronous startup and shutdown lifecycles

292

*/

293

interface ApiService {

294

/**

295

* If the service state is NEW, this initiates service startup and returns immediately

296

* @return This service instance

297

*/

298

ApiService startAsync();

299

300

/**

301

* If the service is STARTING or RUNNING, this initiates service shutdown and returns immediately

302

* @return This service instance

303

*/

304

ApiService stopAsync();

305

306

/**

307

* Waits for the Service to reach the RUNNING state

308

* @throws IllegalStateException If the service reaches a state other than RUNNING

309

*/

310

void awaitRunning();

311

312

/**

313

* Waits for the Service to reach the RUNNING state for no more than the given time

314

* @param timeout The maximum time to wait

315

* @param unit The time unit of the timeout argument

316

* @throws TimeoutException If the service does not reach RUNNING within the timeout

317

* @throws IllegalStateException If the service reaches a state other than RUNNING

318

*/

319

void awaitRunning(long timeout, TimeUnit unit) throws TimeoutException;

320

321

/**

322

* Waits for the Service to reach the TERMINATED state

323

* @throws IllegalStateException If the service fails

324

*/

325

void awaitTerminated();

326

327

/**

328

* Waits for the Service to reach the TERMINATED state for no more than the given time

329

* @param timeout The maximum time to wait

330

* @param unit The time unit of the timeout argument

331

* @throws TimeoutException If the service does not reach TERMINATED within the timeout

332

* @throws IllegalStateException If the service fails

333

*/

334

void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException;

335

336

/**

337

* Returns true if this service is RUNNING

338

* @return True if the service is running

339

*/

340

boolean isRunning();

341

342

/**

343

* Returns the current state of this service

344

* @return The current service state

345

*/

346

State state();

347

348

/**

349

* Returns the Throwable that caused this service to fail

350

* @return The failure cause, or null if the service has not failed

351

*/

352

Throwable failureCause();

353

354

/**

355

* Registers a Listener to be executed on the given executor

356

* @param listener The listener to register

357

* @param executor The executor to run the listener on

358

*/

359

void addListener(Listener listener, Executor executor);

360

361

/**

362

* The lifecycle states of a service

363

*/

364

enum State {

365

NEW, STARTING, RUNNING, STOPPING, TERMINATED, FAILED

366

}

367

368

/**

369

* A listener for the various state changes that a Service goes through in its lifecycle

370

*/

371

abstract class Listener {

372

/**

373

* Called when the service transitions from NEW to STARTING

374

*/

375

public void starting() {}

376

377

/**

378

* Called when the service transitions from STARTING to RUNNING

379

*/

380

public void running() {}

381

382

/**

383

* Called when the service transitions to the STOPPING state

384

* @param from The previous state

385

*/

386

public void stopping(State from) {}

387

388

/**

389

* Called when the service transitions to the TERMINATED state

390

* @param from The previous state

391

*/

392

public void terminated(State from) {}

393

394

/**

395

* Called when the service transitions to the FAILED state

396

* @param from The previous state

397

* @param failure The failure that caused the transition

398

*/

399

public void failed(State from, Throwable failure) {}

400

}

401

}

402

```

403

404

### AbstractApiService

405

406

Base implementation of `ApiService` that handles state management and listener notification. Subclasses only need to implement the actual start and stop logic.

407

408

```java { .api }

409

/**

410

* Base implementation of ApiService

411

*/

412

abstract class AbstractApiService implements ApiService {

413

/**

414

* Invoked to start the service. This method should be idempotent

415

*/

416

protected abstract void doStart();

417

418

/**

419

* Invoked to stop the service. This method should be idempotent

420

*/

421

protected abstract void doStop();

422

423

/**

424

* Implementing classes should invoke this method once their service has started

425

*/

426

protected final void notifyStarted();

427

428

/**

429

* Implementing classes should invoke this method once their service has stopped

430

*/

431

protected final void notifyStopped();

432

433

/**

434

* Invoke this method to transition the service to the FAILED state

435

* @param cause The exception that caused the service to fail

436

*/

437

protected final void notifyFailed(Throwable cause);

438

}

439

```

440

441

**Usage Example:**

442

443

```java

444

import com.google.api.core.AbstractApiService;

445

446

public class MyService extends AbstractApiService {

447

private volatile boolean running = false;

448

449

@Override

450

protected void doStart() {

451

// Start your service logic here

452

new Thread(() -> {

453

try {

454

// Initialize resources

455

running = true;

456

notifyStarted(); // Signal that startup completed

457

458

// Run service loop

459

while (running) {

460

// Service work

461

Thread.sleep(1000);

462

}

463

} catch (Exception e) {

464

notifyFailed(e); // Signal failure

465

}

466

}).start();

467

}

468

469

@Override

470

protected void doStop() {

471

running = false;

472

// Cleanup resources

473

notifyStopped(); // Signal that shutdown completed

474

}

475

}

476

477

// Usage

478

MyService service = new MyService();

479

service.startAsync().awaitRunning();

480

// Service is now running

481

service.stopAsync().awaitTerminated();

482

// Service is now stopped

483

```

484

485

### Clock Abstractions

486

487

Abstraction for time sources that can be mocked in tests, providing both high-resolution nanosecond timing and standard millisecond timing.

488

489

```java { .api }

490

/**

491

* A supplier of time values

492

*/

493

interface ApiClock {

494

/**

495

* Returns the current value of the running JVM's high-resolution time source, in nanoseconds

496

* @return The current value of the running JVM's high-resolution time source, in nanoseconds

497

*/

498

long nanoTime();

499

500

/**

501

* Returns the current time in milliseconds

502

* @return The difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC

503

*/

504

long millisTime();

505

}

506

507

/**

508

* A Clock that returns the current system nano time

509

*/

510

class NanoClock implements ApiClock {

511

/**

512

* Returns the default NanoClock instance

513

* @return The default clock instance

514

*/

515

static ApiClock getDefaultClock();

516

517

@Override

518

public long nanoTime() {

519

return System.nanoTime();

520

}

521

522

@Override

523

public long millisTime() {

524

return java.util.concurrent.TimeUnit.MILLISECONDS.convert(nanoTime(), java.util.concurrent.TimeUnit.NANOSECONDS);

525

}

526

}

527

528

/**

529

* A Clock that returns the current system time in milliseconds

530

*/

531

class CurrentMillisClock implements ApiClock {

532

/**

533

* Returns the default CurrentMillisClock instance

534

* @return The default clock instance

535

*/

536

static ApiClock getDefaultClock();

537

538

@Override

539

public long nanoTime() {

540

return java.util.concurrent.TimeUnit.NANOSECONDS.convert(millisTime(), java.util.concurrent.TimeUnit.MILLISECONDS);

541

}

542

543

@Override

544

public long millisTime() {

545

return System.currentTimeMillis();

546

}

547

}

548

```

549

550

### Base Future Classes

551

552

Abstract base classes for implementing custom `ApiFuture` types and forwarding decorators.

553

554

```java { .api }

555

/**

556

* An abstract implementation of ApiFuture, for easier extension

557

* @param <V> The result type returned by this Future's get method

558

*/

559

abstract class AbstractApiFuture<V> implements ApiFuture<V> {

560

/**

561

* Sets the result of this AbstractApiFuture unless it has already been cancelled or set

562

* @param value The value to set

563

* @return True if the value was set, false if the future was already complete

564

*/

565

protected boolean set(V value);

566

567

/**

568

* Sets the result of this AbstractApiFuture to the given exception unless it has already been cancelled or set

569

* @param throwable The exception to set

570

* @return True if the exception was set, false if the future was already complete

571

*/

572

protected boolean setException(Throwable throwable);

573

574

/**

575

* Subclasses can override this method to be notified when this future is cancelled

576

*/

577

protected void interruptTask();

578

}

579

580

/**

581

* A Future that forwards all calls to another future

582

* @param <T> The result type returned by this Future's get method

583

*/

584

class ForwardingApiFuture<T> implements ApiFuture<T> {

585

/**

586

* Constructor that takes the delegate future

587

* @param delegate The future to forward calls to

588

*/

589

protected ForwardingApiFuture(ApiFuture<T> delegate);

590

}

591

```