Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Promises in Java: Using Promises to Recover from Failure

26 views

Published on

Provide an overview of Promises in Java and show how powerful they are for solving complex issues with little code.

Communications is error prone. Connections time out, servers fail to respond, returned data can be incomplete or corrupted. Bnd, the OSGi tooling project, has an HttpClient class which is used for communications including with remote repositories like Maven/Nexus and P2 repositories. The Bnd CI builds started having significant failures due to communications problems with the Eclipse download servers, so with some light code restructuring, I was able to add retry support to HttpClient using the Promises package from OSGi. This session will take a look at the Promises package and how it was easily used to recover from communications failures.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Promises in Java: Using Promises to Recover from Failure

  1. 1. Promises in Java: Using Promises to Recover from Failure BJ Hargrave IBM
  2. 2. What is a Promise? 2
  3. 3. 3 • A Promise object holds the eventual result of a potentially asynchronous task. • A Promise is either unresolved or resolved. • An unresolved Promise does not have the result of the associated task available while a resolved Promise has the result of the associated task available. • A resolved Promise can be either resolved with a value, which means the associated task completed successfully and supplied a result, or resolved with a failure, which means the associated task completed unsuccessfully and supplied an exception.
  4. 4. https://osgi.org/specification/osgi.cmpn/7.0.0/util.promise.html
  5. 5. Monadic
  6. 6. Chaining Promises 9 • Promises can be chained • Methods on Promise can return a new Promise chained to the original promise • Each promise in the chain is used to resolve the next promise in the chain with some possible mutation of the result/failure
  7. 7. Chaining Example 10 Promise<String> name = getDownloadName(); Promise<URL> mirror = name.flatMap(p -> getMirror(p)); Promise<File> file = mirror.flatMap(p -> getFile(p)); Since we probably do not need the intermediate Promises, we can collapse the chain into a single statement: Promise<File> file = getDownloadName() .flatMap(this::getMirror) .flatMap(this::getFile);
  8. 8. Using Promises to Recover from Failure 11
  9. 9. Bnd 12 • Bnd is open source tooling to build OSGi bundles • Bnd provides Eclipse, Maven, and Gradle plugins • Bnd has support for Maven/Nexus, Eclipse P2, and other remote artifact repositories • https://github.com/bndtools/bnd
  10. 10. Bnd’s HttpClient 13 • For communications, Bnd has its own HttpClient class • This is for historical reasons and to minimize dependencies on 3rd party communications packages • Recent reliability issues with P2 repositories on Eclipse’s download site caused us to add retry support to the HttpClient class • The HttpClient class already had synchronous and asynchronous request methods • The asynchronous request method already returns a Promise 
  11. 11. Changes to add Recovery support 14 • Change async method to add retry support • Retry count with delay • Timeout for connection and read hangs • Server side 5XX errors and IOException failures • Change sync method to use async method which now has retry support • Uses a Promise blocking method to synchronously wait for result • Through the “magic” of Promise chaining, we can further add checksum validation and checksum failure retry logic
  12. 12. Recovery functions
  13. 13. Code
  14. 14. Coordinates <dependency> <groupId>org.osgi</groupId> <artifactId>osgi.promise</artifactId> <version>7.0.1</version> </dependency>
  15. 15. CompletableFuture 18 • Introduced in Java 8 and expanded in Java 9 • A promise type in the Java platform but… • Has a large and unwieldy API • Odd method names • Combines resolving promise with using promise • Mutable • Promise is a one-way latch – one-time resolve • CompletableFuture can be resolved repeatedly - obtrude
  16. 16. 19 CompletionStage Promise thenApply map thenCompose flatMap exceptionally recover handle then thenRun onResolve whenComplete onSuccess/onFailure
  17. 17. 20 CompletableFuture Promise supplyAsync/runAsync PromiseFactory.submit allOf PromiseFactory.all complete Deferred.resolve completeExceptionally Deferred.fail completedFuture PromiseFactory.resolved failedFuture PromiseFactory.failed <init> PromiseFactory.deferred cancel X delayedExecutor delay orTimeout timeout isDone isDone get getValue/getFailure
  18. 18. Thanks!

×