Repository navigation
Wait on a future inside a generic wrapper whose transformer returns a future - #941
Merged
Merged
Conversation
GenericWrapper.withCompletionStageTransformer registers a wrapper whose transformer returns a future of its content, like Mono::toFuture. The unwrapper then waits on that future before the declared one, so Mono<CompletableFuture<Item>> resolves to the Item. Wrappers registered with withTransformer keep handing their result to a declared future as is.
|
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.



Description
Fixes #938
A generic wrapper registered with a transformer that returns a future of its content, like Reactor's
MonowithMono::toFuture, lost a future when its type argument was itself a future. ForMono<CompletableFuture<Item>>,{ item { name } }failed withand a
Mono<CompletionStage<String>>field returned"java.util.concurrent.CompletableFuture@4d3c6593[Completed normally]"with no error. Same inside lists and other wrappers.The unwrapper hands a wrapper's transformer result straight to the declared future below it. That's right for a
Try<CompletableFuture<Item>>whose transformer returns the declared future (graphql-java gets the resolver's own future), butMono::toFuturereturns a future of it. Both build the same steps, and only the completed value tells them apart. Checking that would add athenComposeon every wrapper around a future and misread union members that implementFuture, so the wrapper has to say it.Now:
GenericWrapper.withCompletionStageTransformer(Mono::class, 0, Mono<*>::toFuture)(or(Mono.class, 0, Mono::toFuture)from Java) registers a wrapper whose transformer returns aCompletionStageof its content. The unwrapper waits on that future first, then on the declared one, at the top level and nestedwithTransformerbehave as before, so aMonoregistered that way still has the bug. Nothing is guessed at runtimeGenericWrapperitself is unchanged (constructor,copy,componentN). The factory marks the transformer instead, andcopykeeps it since it keeps the transformerI first had the flag as a new
GenericWrapperproperty. Keeping the old JVM signatures then needs a hand-written 4-parameter constructor andcopythat read as dead code, and a caller could set the flag on a transformer that returns the content. With the factory, the transformer's type has to be aCompletionStage.No
DataFetchingEnvironmentorschemaWrapperoverloads, since nobody asked for them. Easy to add later.Release note:
GenericWrapper.withCompletionStageTransformerregisters a wrapper whose transformer returns a future of its content, such as Reactor'sMono::toFuture. A future declared inside it, likeMono<CompletableFuture<Item>>, is then waited on too. Before, graphql-java got the inner future as the value. Wrappers registered withwithTransformerkeep their behaviour.Checklist
mvn clean verifypasses (440 tests). New tests inNestedGenericWrapperTestcover the future at the top level, a scalar, a list, and a union member that implementsFuture. The first three fail without the unwrapper change.Also checked through the installed jar in a separate consumer project with reactor-core 3.7.19. With
withCompletionStageTransformer,Mono<CompletableFuture<Item>>,List<Mono<CompletableFuture<Item>>>,Mono<CompletionStage<String>>andTry<Mono<CompletableFuture<Item>>>all resolve. WithwithTransformerthey still fail like on master. A Java caller compiles with-Xlint:all -Werror(apart from the rawMono.class), andjavapagainst 14.5.0 shows no removed or changedGenericWrappersignature.The bounded check of every return type up to 3 containers deep (about 172k executions), with its future-returning wrapper registered through the new factory, no longer finds the 192 failing return types it finds on master, and finds nothing new.