Enable JDK promise support and start to support reactive pipeline all the way - #6012
rmannibucau wants to merge 1 commit into
Conversation
FroMage
left a comment
There was a problem hiding this comment.
This is much larger than my proposal, and more complete in terms of supporting async types for parallel execution.
Unlike my proposal though, it does not support pluggable async types, so as such it is not very reactive-framework-friendly.
It also does not support a pluggable way to offload the original test method onto the proper reactive context (the event loop), but I have to investigate if this could be achieved by a JUnit interceptor (depends if they have access to the method return value, I guess).
| static final AtomicInteger beforeEachCount = new AtomicInteger(); | ||
| static final AtomicInteger afterEachCount = new AtomicInteger(); | ||
|
|
||
| @BeforeEach |
There was a problem hiding this comment.
Are lifecycle methods that return an async type also supported?
There was a problem hiding this comment.
Very good point and no I missed it, will work on that
| */ | ||
| public static boolean isFullySupported(Class<?> type) { | ||
| Preconditions.notNull(type, "type must not be null"); | ||
| return CompletionStage.class.isAssignableFrom(type) || Future.class.isAssignableFrom(type); |
There was a problem hiding this comment.
The problem with this is that it artificially limits the usable async types. We don't use those types in Quarkus, we use Uni, in Vert.x they use a different Future, in Spring they use Mono…
All of which can be converter to a CompletionStage easily, but this PR is missing the SPI to achieve it.
Otherwise every test will have to end with .convertToCompletionStage() which is just unnecessary boilerplate for users.
There was a problem hiding this comment.
yes, my approach is that it is less critical to have to add a call which doesn't break the execution model than to not be able to use a programming model at all but agree we'll need to enable what you PR goal is. I just didn't want to do it before the API/SPI is fully reactive friendly cause it is likely it misses the line otherwise (it is already a lot of rework in this PR to say it differently).
does it sound ok to finish this one then add "your" feature on top - and I totally agree it will be better but what I'm not sure today is that a new API will be needed, I hope we can make it functional with interceptors or something existing even if totally unsure yet?
There was a problem hiding this comment.
Well, if you don't introduce a new API/SPI, you'll have to use converting libraries such as https://github.com/smallrye/smallrye-reactive-converters/tree/main/reactive-converters which would be fine for us.
ead98ab to
1349e04
Compare
Signed-off-by: Romain Manni-Bucau <rmannibucau@gmail.com>
1349e04 to
e92a1b3
Compare
✅ All tests passed ✅Test SummaryCI / Build / Linux > :platform-tooling-support-tests:test
🏷️ Commit: e92a1b3 Test FailuresMemoryCleanupTests > runsWithSmallHeapSize(OutputFiles, OutputFiles) (:platform-tooling-support-tests:test in CI / Build / Linux)Learn more about TestLens at testlens.app/docs. |
|
up? |
|
@rmannibucau Thanks for the PR! Since #5292 is waiting for additional interest from the community, reviewing this PR is not a priority for us at the moment. |
|
@rmannibucau I just tested it and it does work for us. It's a little less than what I provided in my PR in the sense that we can't control the execution of the test method to offload it to another thread (we can only convert its return value), but we can achieve that offloading via another sort of interceptor, so we can work around it. |
my idea was that the promise controls the thread so it was built-in by design, did I miss sthg? |
|
As far as I can see, I can only control what happens in the But again, I can work around that. The other thing I can think of is that |
|
@FroMage yep but the first one is the trigger which must not block (else it is pointless to use this programming model) so second is sufficient from my view and is always workaround-able using supplyAsync(,pool) |
|
It's not just about blocking: in our case the creation of these async tasks must happen on an event loop, so we need to redirect the execution of the test method on the event loop, because we can start making those promises. Anyway, as I said, we can work around it using other kinds of interceptors. The biggest hurdle was the method return type being disallowed. |
|
@FroMage the point is more that you can always do it in a promise or using an injected helper which does facade a queue push/pop using completionstages. That said I get it but also brings the context in the loop issue generally speaking so maybe your interceptor (or a parameter/field injection) is saner 🤔 . Anyway if this PR already enables your case I see it as a baby step forward ;) |
|
Yeah, as I said, at this point, both my PR (less complete, but smaller) or yours achieve our goals, so I'm good with either one, I just hope we can get any merged soon so I don't have to commit atrocious classloader mocks to workaround this 😬 |
proposed solution to #5292
I hereby agree to the terms of the JUnit Contributor License Agreement.
Definition of Done
@APIannotations