Make the 51Did Java client asynchronous only - #129
Open
jwrosewell wants to merge 1 commit into
Open
Conversation
Every DidClient method that can reach the 51Degrees cloud now answers through a CompletableFuture and the blocking versions are gone, so a server handling a request never holds its thread while the cloud is asked. publicKeys, publicKeyFor, verifySignature, verifySignatureDetailed, verify and redeem keep their names and their arguments and return a CompletableFuture of what they returned before. None of them declares IOException any more, and nothing they refuse before the cloud is called is thrown either, so every failure reaches a caller the same way, as the cause of the CompletionException a future reports. HttpTransport.send answers a CompletableFuture<Response> as well. Java 8 has no non-blocking HTTP client in its standard library, so the default transport still uses HttpURLConnection and runs the exchange on an executor, which the builder can now be given with executor(Executor) and which is otherwise a small bounded pool of daemon threads. On Java 11 and later a transport over java.net.http.HttpClient.sendAsync needs no thread per request. The key cache works as it did, except that callers arriving while a fetch is under way now wait on that one fetch rather than starting another, which matters more now that several requests can be in flight at once. The two step verification, the licence key handling, the redeem outcome types, the key selection by latest start at or before the date and the handling of every status the cloud answers with are all unchanged, and the tests that pin them are converted rather than rewritten. The demo server's /redeem route composes the two calls and maps a failure in one place, and the READMEs and the package documentation describe the asynchronous client and how to move off the blocking one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Every method on
DidClientthat reaches the cloud now returns aCompletableFutureand the synchronous forms are removed outright. This is one of a set of changes making every 51Did client and every OWID port asynchronous where the network is involved, so the libraries behave the same way in every language.Methods that never touch the network are untouched, so
getResourceKey,getEndpoint,hasLicenceKeyand the staticsparseKeys,inForceAt,candidatesFor,resolveEndpointandencodeare as they were.FodIdis not touched, because another branch is changing it.Removed
New
The same eight, each returning
CompletableFutureof what it returned before, plus:The build stays at Java 8, which has no non-blocking HTTP client in the standard library, so the default transport runs the existing
HttpURLConnectionexchange on anExecutorbacked by a bounded pool of daemon threads. The documentation says plainly that this is blocking work on a background thread, and that a caller on Java 11 or later can supply a transport overjava.net.http.HttpClient.sendAsyncinstead. The executor belongs to the default transport; a transport of your own schedules its own work.Failure contract
Every failure the client reports is now the cause of a
CompletionException, including input it refuses before the cloud is called, soverify(String)andredeem(...)no longer throwIllegalArgumentExceptionat the caller. A transport that throws instead of failing its future, or that answers null, is reported the same way rather than leaving a caller waiting for ever.Kept exactly
The two step verification, licence key handling, the redeem outcome types, key selection by the latest start at or before the date, and the 401 handling, all still pinned by their original tests. The key list cache now shares one in-flight fetch between concurrent callers.
Verification
mvn -pl pipeline.did -am testmvn -DskipTests packagemvn -pl ...developer-examples.fodid -am testDidClientTestswent from 63 tests to 68. The new ones cover two concurrent key list requests making one HTTP call, a failed shared fetch reaching every waiter and leaving the next caller to start its own, the builder's executor receiving the blocking work, and the default transport reporting both a failed exchange and a refused executor through the future. Thirteen tests whose names said "Raises" now say "Fails", since they no longer test a thrown exception.The module compiles under the project's
-Xlint:allwith-Werroron JDK 21. The URL is built withURI.create(...).toURL()rather than theURL(String)constructor, which is deprecated from Java 20 and would fail that leg.Notes
Written with AI assistance and reviewed before merging. This client uses only the OWID library's cryptography and not its fetch, so it does not wait on the OWID asynchronous work in SWAN-community.