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
```