Hi Andrey, I agree that public API based on CompletableFuture might be very useful. The thing I worry about is that with CompletableFuture used internally we can miss some important capabilities (e.g. mentioned cancellation). ReactiveStreams specification on the other hand defines a lot of interesting and important things and it can serve as guidance for Ignite developers.
So, my vision here is that it is very important to have well-defined semantics internally. Introducing public API based on CompletableFuture is fine as well because enough users can be quite happy with it. 2021-04-05 14:49 GMT+03:00, Andrey Mashenkov <andrey.mashen...@gmail.com>: > Hi Ivan, > > JDK flow API looks interesting. I think we should use it abroad. > Though, Java 14 is not LTS (long-term support) release. I guess many users > will prefer Java 15, > but actually, we have no agreement about switching to Java 15 which may > require some additional efforts. > For now, we could import the required classes into Ignite module as we've > done with JSR-166 (concurrent collections). > > I think we should use Flow-like API for Queries, Cursors, Compute results > and even Transactions. > E.g. reactive transaction API is must have and it can be looked like: > Transaction.compose(tx -> table1.getAsync(a)).thenApply(tx -> > table2.putAsync()).thenApply(tx -> tx.commit()); > > Agree, CompletableFuture looks totally unusable for cases that supposed > cancellation capabilities, due to broken cancellation semantic [1]. > However, cancellation support for simple table operations doesn't make any > sense and we still can use CompletableFuture for e.g. table operations > unless we found it unusable for Transaction API that is not designed yet. > > I've looked at reactive API as CompletableFuture replacement for simple > cases. > At first glance, it is very complex and may require too much effort on our > user side, and/or hard to understand for the user. > > Maybe it make sense to create an IEP for future replacement with all the > examples for the table, transaction, compute APIs? > WDYT? > > [1] > https://stackoverflow.com/questions/43389894/recursively-cancel-an-allof-completablefuture > > On Sat, Apr 3, 2021 at 1:40 AM Ivan Pavlukhin <vololo...@gmail.com> wrote: > >> Andrey, >> >> As you might know Java has it is own Reactive abstractions since 9 >> [1]. Moreover, an original Reactive Streams library has a bridge with >> Java [2]. >> >> Personally I do not love CompletableFuture because it's API seems >> questionable to me in various aspects, e.g. mentioned cancellation. >> Currently I think that the cleanest way is custom abstractions >> (possibly implementing CompletionStage) at first. And providing >> bridges to other APIs (including CompletableFuture) as a next step. >> Various API integrations can come in form of extensions. >> >> > JDK classes are well-known and reactive frameworks usually have >> converters >> to/from CompletableFuture [1] [2]. >> >> Here I have doubts that it is feasible to achieve it fairly. E.g. once >> again cancellation. While reactive API supports cancellation it will >> not be possible to cancel computation for anything built from >> CompletableFuture. >> >> [1] >> https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/concurrent/Flow.Publisher.html >> [2] >> https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/org/reactivestreams/FlowAdapters.html >> >> 2021-04-02 12:00 GMT+03:00, Andrey Mashenkov >> <andrey.mashen...@gmail.com>: >> > Ivan, >> > thanks for the link. I think, now I've got what you mean. >> > >> > I don't think we want to have any framework as a dependency and rely on >> > their lifecycle, roadmaps goals and >> > bother about compatibility. >> > JDK classes are well-known and reactive frameworks usually have >> converters >> > to/from CompletableFuture [1] [2]. >> > So, users are free to choose any reactive framework. >> > >> > I think will need reactive abstractions in near future for Queries API >> and >> > maybe Transaction API design. >> > These projects are good enough where we can get inspiration. >> > >> > [1] >> > >> https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#fromFuture-java.util.concurrent.CompletableFuture- >> > [2] >> > >> https://github.com/ReactiveX/RxJava/blob/3.x/src/main/java/io/reactivex/rxjava3/internal/jdk8/CompletableFromCompletionStage.java >> > >> > On Thu, Apr 1, 2021 at 1:29 PM Ivan Pavlukhin <vololo...@gmail.com> >> wrote: >> > >> >> Andrey, >> >> >> >> > Reactive abstractions look more suitable for Queries rather than >> >> > cache/table async operations and don't offer the power of chaining >> like >> >> > CompletableStage. >> >> >> >> Could you please elaborate what capabilities do you mean? AFAIK there >> >> are quite powerful APIs for singular reactive abstractions as well. >> >> E.g. [1]. >> >> >> >> [1] >> >> >> https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html >> >> >> >> 2021-04-01 12:33 GMT+03:00, Andrey Mashenkov >> >> <andrey.mashen...@gmail.com>: >> >> > Val, >> >> > I just complain JDK CompletableFuture itself is not ideal, but >> >> > already >> >> > implemented, well-known and tested. >> >> > It still a good alternative compared to custom future implementation >> to >> >> me. >> >> > >> >> > Ok, I feel most of us agree with CompletableFuture as a replacement >> for >> >> > custom IgniteFuture. >> >> > Let's try to use it, but keep in mind that we MUST return a >> >> > defective >> >> copy >> >> > (via copy() or minimalStage()) to user to prevent misusage on the >> >> > user >> >> > side. >> >> > It would be nice if we'll follow the same requirement in our >> >> > internal >> >> code, >> >> > e.g. if a component returns a future that further can be used in >> >> > other >> >> > components, especially in custom plugins. >> >> > >> >> > Ivan, thanks for the example. >> >> > Reactive abstractions look more suitable for Queries rather than >> >> > cache/table async operations and don't offer the power of chaining >> like >> >> > CompletableStage. >> >> > AFAIK, guys who involved in SQL engine development based on Calcite >> >> already >> >> > use reactive patterns. >> >> > >> >> > >> >> > On Thu, Apr 1, 2021 at 3:15 AM Ivan Pavlukhin <vololo...@gmail.com> >> >> wrote: >> >> > >> >> >> Folks, >> >> >> >> >> >> Regarding Reactive abstractions. While it might look too complex >> >> >> for >> >> >> simple KV cases it can be quite powerful for queries. Also there >> >> >> are >> >> >> known solutions for cancellation, backpressure and flow control. It >> >> >> can greatly simplify things for users familiar with Reactive >> >> >> programming rather than learning Ignite-specific Query/QueryCursor >> >> >> API. >> >> >> >> >> >> Also it looks like there are well-defined semantics [1]. E.g. >> >> >> cancellation seems to be defined much better than for >> >> >> CompletableFuture. >> >> >> >> >> >> [1] >> >> >> >> https://github.com/reactive-streams/reactive-streams-jvm#specification >> >> >> >> >> >> 2021-03-31 21:30 GMT+03:00, Valentin Kulichenko < >> >> >> valentin.kuliche...@gmail.com>: >> >> >> > Hi Andrey, >> >> >> > >> >> >> > Please see below. >> >> >> > >> >> >> > -Val >> >> >> > >> >> >> > On Wed, Mar 31, 2021 at 7:55 AM Andrey Mashenkov >> >> >> > <andrey.mashen...@gmail.com> >> >> >> > wrote: >> >> >> > >> >> >> >> CompletableFuture cancellation will not work as many users >> >> >> >> expected. >> >> >> >> Javadoc says: >> >> >> >> /* Since (unlike {@link FutureTask}) this class has no direct >> >> >> >> * control over the computation that causes it to be completed, >> >> >> >> * cancellation is treated as just another form of exceptional >> >> >> >> * completion. >> >> >> >> */ >> >> >> >> >> >> >> > >> >> >> > Let's not make assumptions about the expectations of the users. >> >> >> > That's >> >> >> > exactly why I initially leaned towards a custom interface as >> >> >> > well, >> >> >> > but >> >> >> > that's a mistake. >> >> >> > Indeed, this contract might look weird to us, because the current >> >> >> > version >> >> >> > of Ignite behaves differently. However, there are much more >> >> >> > developers >> >> >> > using CompletableFuture and other standard async frameworks, than >> >> >> > developers using the async functionality of Ignite. Therefore, >> >> >> > our >> >> >> > intuitions can easily be wrong. >> >> >> > >> >> >> > >> >> >> >> Completion of a child future doesn't trigger the completion of a >> >> >> >> parent. >> >> >> >> So, we will need to extend the future anyway. >> >> >> >> >> >> >> > >> >> >> > First of all, as Pavel mentioned, you can attach your own >> >> >> > listener >> >> >> > before >> >> >> > returning a CompletableFuture to the user. You don't need to >> extend. >> >> >> > Second of all, there is still a discussion to be had on whether >> >> >> > the >> >> >> parent >> >> >> > needs to be completed. I don't actually think it's obvious, and >> most >> >> >> likely >> >> >> > it's case by case. With CompletableFuture you have enough >> >> >> > flexibility >> >> >> > to >> >> >> > control the behavior. >> >> >> > >> >> >> > >> >> >> >> >> >> >> >> Also, cancel() method contract differs from IgniteFuture in 2.0, >> >> >> >> Completable method return true if the future was cancelled, >> >> >> >> but IgniteFuture return true only if it wasn't cancel prior the >> >> >> >> call. >> >> >> >> Thus, if cancel() was called twice we will have different >> >> >> >> results >> >> >> >> for >> >> >> >> CompletableFuture and IgniteFuture, >> >> >> >> that makes CompletableFuture barely usable for our internal >> >> >> >> purposes. >> >> >> >> >> >> >> > >> >> >> > It doesn't really matter how IgniteFuture in 2.0 behaves. It was >> >> >> > created >> >> >> > long before continuations and other async concepts became >> mainstream >> >> >> > (in >> >> >> > Java world at least). >> >> >> > Also, we don't have to use it for internal purposes, of course. >> >> >> > I'm >> >> >> > only >> >> >> > talking about public APIs. >> >> >> > >> >> >> > >> >> >> >> >> >> >> >> BTW, CompletableFuture.anyOf() still can be used, see >> >> >> >> CompletionStage.toCompletableFuture() contract. >> >> >> >> >> >> >> > >> >> >> > In my view, this actually kills the idea of a custom future. >> >> Basically, >> >> >> > the proposal is to introduce a custom entity to restrict access >> >> >> > to >> >> some >> >> >> of >> >> >> > the CompletableFuture methods, but then allow to convert this >> custom >> >> >> entity >> >> >> > to a CompletableFuture that has all the methods. This makes zero >> >> >> > sense >> >> >> > to >> >> >> > me. >> >> >> > >> >> >> > >> >> >> >> >> >> >> >> The more I learn about CompletableFuture the stronger my opinion >> >> about >> >> >> >> overriding it. >> >> >> >> >> >> >> >> >> >> >> >> On Wed, Mar 31, 2021 at 9:31 AM Denis Garus >> >> >> >> <garus....@gmail.com> >> >> >> wrote: >> >> >> >> >> >> >> >> > > Stripping them from such functionality, which they are used >> to, >> >> is >> >> >> >> > > most >> >> >> >> > likely a bad idea. >> >> >> >> > >> >> >> >> > Completely agree with this point of view. >> >> >> >> > Moreover, a user can pass CompletableFuture to another library >> to >> >> do >> >> >> >> > any >> >> >> >> > manipulations. >> >> >> >> > So if we want to introduce our class instead of the java >> >> >> >> > class, >> >> >> >> > we >> >> >> >> > should >> >> >> >> > have solid arguments; >> >> >> >> > otherwise, it can be a reason for irritation. >> >> >> >> > >> >> >> >> > ср, 31 мар. 2021 г. в 09:06, Pavel Tupitsyn < >> ptupit...@apache.org >> >> >: >> >> >> >> > >> >> >> >> > > Val, >> >> >> >> > > >> >> >> >> > > > we can have an IgniteFuture that extends >> >> >> >> > > > CompletableFuture. >> >> >> >> > > > This might be useful if want the cancel() operation to >> cancel >> >> >> >> > > > the >> >> >> >> > > > underlying operation >> >> >> >> > > >> >> >> >> > > I think we can subscribe to the cancellation of the >> >> >> CompletableFuture >> >> >> >> > > and cancel the underlying operation without an extra class, >> >> >> >> > > something like >> >> >> >> > > >> >> >> >> > > fut.exceptionally(t -> { >> >> >> >> > > if (t instanceof CancellationException) { >> >> >> >> > > // Cancel Ignite operation >> >> >> >> > > } >> >> >> >> > > }); >> >> >> >> > > >> >> >> >> > > On Wed, Mar 31, 2021 at 7:45 AM Valentin Kulichenko < >> >> >> >> > > valentin.kuliche...@gmail.com> wrote: >> >> >> >> > > >> >> >> >> > > > These are actually some interesting points. As I'm >> >> >> >> > > > thinking >> >> more >> >> >> >> about >> >> >> >> > > > this, I'm leaning towards changing my opinion and voting >> >> >> >> > > > for >> >> the >> >> >> >> > > > CompletableFuture. Here is my reasoning. >> >> >> >> > > > >> >> >> >> > > > First, it's important to keep in mind that >> >> >> >> > > > CompletableFuture >> >> >> >> > > > is >> >> >> not >> >> >> >> an >> >> >> >> > > > interface that we will implement, it's an implemented >> >> >> >> > > > class. >> >> >> >> Therefore, >> >> >> >> > > > some of the concerns around complete() and cancel() method >> >> >> >> > > > are >> >> >> >> > > > not >> >> >> >> > really >> >> >> >> > > > relevant -- it's not up to us how these methods behave, >> >> >> >> > > > they're >> >> >> >> already >> >> >> >> > > > implemented. >> >> >> >> > > > >> >> >> >> > > > Second, CompletableFuture does provide some useful >> >> functionality >> >> >> >> (anyOf >> >> >> >> > > is >> >> >> >> > > > one of the examples). I can even envision users wanting to >> >> >> complete >> >> >> >> the >> >> >> >> > > > future under certain circumstances, e.g. after a timeout, >> >> >> >> > > > using >> >> >> >> > > > the completeOnTimeout method. Stripping them from such >> >> >> >> > > > functionality, >> >> >> >> > > which >> >> >> >> > > > they are used to, is most likely a bad idea. >> >> >> >> > > > >> >> >> >> > > > And finally, we can have an IgniteFuture that extends >> >> >> >> > CompletableFuture. >> >> >> >> > > > This might be useful if want the cancel() operation to >> cancel >> >> >> >> > > > the >> >> >> >> > > > underlying operation. This way we keep all the >> >> >> >> > > > functionality >> >> >> >> > > > of >> >> >> >> > > > CompletableFuture while keeping a certain amount of >> >> >> >> > > > flexibility >> >> >> for >> >> >> >> > > > specific cases. >> >> >> >> > > > >> >> >> >> > > > Thoughts? >> >> >> >> > > > >> >> >> >> > > > -Val >> >> >> >> > > > >> >> >> >> > > > >> >> >> >> > > > On Tue, Mar 30, 2021 at 5:36 AM Denis Garus >> >> >> >> > > > <garus....@gmail.com> >> >> >> >> > wrote: >> >> >> >> > > > >> >> >> >> > > > > > Completing future from outside will never respect >> >> >> >> > > > > > other >> >> >> >> subscribers >> >> >> >> > > > that >> >> >> >> > > > > > may expect other guatantees. >> >> >> >> > > > > >> >> >> >> > > > > For example, if we talk about public API like >> >> >> >> > > > > IgniteCache, >> >> >> >> > > > > what >> >> >> >> > > > subscribers >> >> >> >> > > > > may expect other guatantees? >> >> >> >> > > > > IMHO, the best solution is to get the well-known >> >> >> >> > > > > standard >> >> >> >> > > > > interface >> >> >> >> > to >> >> >> >> > > a >> >> >> >> > > > > user, and he will be happy. >> >> >> >> > > > > >> >> >> >> > > > > But when we talk about internal classes like "exchange >> >> future" >> >> >> >> > > > > they >> >> >> >> > > could >> >> >> >> > > > > be custom futures if convenient. >> >> >> >> > > > > >> >> >> >> > > > > вт, 30 мар. 2021 г. в 15:25, Atri Sharma >> >> >> >> > > > > <a...@apache.org >> >: >> >> >> >> > > > > >> >> >> >> > > > > > IMO the only way Ignite should cancel computations is >> iff >> >> >> >> > > > > > cancel >> >> >> >> > > method >> >> >> >> > > > > is >> >> >> >> > > > > > invoked, not implicitly if complete is invoked. >> >> >> >> > > > > > >> >> >> >> > > > > > On Tue, 30 Mar 2021 at 4:58 PM, Denis Garus >> >> >> >> > > > > > <garus....@gmail.com >> >> >> >> > >> >> >> >> > > > wrote: >> >> >> >> > > > > > >> >> >> >> > > > > > > Hello! >> >> >> >> > > > > > > >> >> >> >> > > > > > > > Let's say a user started a compute with fut = >> >> >> >> > > > compute.runAsync(task); >> >> >> >> > > > > > > > and now calls fut.complete(someVal); Does this >> >> >> >> > > > > > > > mean >> >> that >> >> >> >> Ignite >> >> >> >> > > no >> >> >> >> > > > > > longer >> >> >> >> > > > > > > needs to execute the task? >> >> >> >> > > > > > > > If the task is currently running, does it need to >> >> >> >> > > > > > > > be >> >> >> >> canceled? >> >> >> >> > > > > > > >> >> >> >> > > > > > > Yes, this case looks like Ignite should cancel >> >> >> >> > > > > > > computations >> >> >> >> > > because a >> >> >> >> > > > > > user >> >> >> >> > > > > > > wants to complete the future. Why not? >> >> >> >> > > > > > > If there will be an opportunity to cancel a future, >> why >> >> is >> >> >> it >> >> >> >> > > > > > > a >> >> >> >> > bad >> >> >> >> > > > > > option >> >> >> >> > > > > > > to finish a future through a complete() method? >> >> >> >> > > > > > > >> >> >> >> > > > > > > > If you look at Ignite-2 code, you may found a >> >> >> >> > > > > > > > number >> >> >> >> > > > > > > > of >> >> >> >> places >> >> >> >> > > > where >> >> >> >> > > > > we >> >> >> >> > > > > > > return e.g. exchange futures or partition release >> >> futures. >> >> >> >> > > > > > > > Assume the impact if we will return >> CompletableFuture >> >> >> >> instead, >> >> >> >> > > > which >> >> >> >> > > > > > can >> >> >> >> > > > > > > be completed in 3-rd party plugin by mistake? >> >> >> >> > > > > > > >> >> >> >> > > > > > > If exchange futures or partition release futures can >> be >> >> >> >> returned >> >> >> >> > to >> >> >> >> > > > > 3-rd >> >> >> >> > > > > > > party plugin by mistake, it is poor encapsulation. >> >> >> >> > > > > > > And if it will be IgniteFuter rather than >> >> CompletedFuture, >> >> >> >> > anyway, >> >> >> >> > > > this >> >> >> >> > > > > > can >> >> >> >> > > > > > > harm. >> >> >> >> > > > > > > >> >> >> >> > > > > > > вт, 30 мар. 2021 г. в 13:14, Andrey Mashenkov < >> >> >> >> > > > > > andrey.mashen...@gmail.com >> >> >> >> > > > > > > >: >> >> >> >> > > > > > > >> >> >> >> > > > > > > > Guys, >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > I want to remember there is one more point to pay >> >> >> attention >> >> >> >> to. >> >> >> >> > > > > > > > Extending Future and CompletableStage is more than >> >> >> >> > > > > > > > just >> >> >> >> > prevents >> >> >> >> > > > > > > unexpected >> >> >> >> > > > > > > > behavior if a user completed the future. >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > First of all, it helps us to write safer code as >> >> >> >> > > > > > > > we >> >> >> >> > > > > > > > won't >> >> >> a >> >> >> >> > > method >> >> >> >> > > > > > > contract >> >> >> >> > > > > > > > exposed such methods as to a user as to a >> >> >> >> > > > > > > > developer. >> >> >> >> > > > > > > > If you look at Ignite-2 code, you may found a >> >> >> >> > > > > > > > number >> >> >> >> > > > > > > > of >> >> >> >> places >> >> >> >> > > > where >> >> >> >> > > > > we >> >> >> >> > > > > > > > return e.g. exchange futures or partition release >> >> >> >> > > > > > > > futures. >> >> >> >> > > > > > > > Assume the impact if we will return >> CompletableFuture >> >> >> >> instead, >> >> >> >> > > > which >> >> >> >> > > > > > can >> >> >> >> > > > > > > be >> >> >> >> > > > > > > > completed in 3-rd party plugin by mistake? >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > The suggested approach allows us to don't bother >> >> >> >> > > > > > > > if >> a >> >> >> >> > > > > CompletableFuture >> >> >> >> > > > > > > has >> >> >> >> > > > > > > > to be wrapped or not. >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > On Tue, Mar 30, 2021 at 12:22 PM Alexey Goncharuk >> >> >> >> > > > > > > > < >> >> >> >> > > > > > > > alexey.goncha...@gmail.com> wrote: >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > > Ivan, >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > > My concern with the concept of a user completing >> >> >> >> > > > > > > > > the >> >> >> >> > > > > > > > > future >> >> >> >> > > > > returned >> >> >> >> > > > > > > from >> >> >> >> > > > > > > > > Ignite public API is that it is unclear how to >> >> >> >> > > > > > > > > interpret >> >> >> >> this >> >> >> >> > > > > action >> >> >> >> > > > > > > > (this >> >> >> >> > > > > > > > > backs Val's message). >> >> >> >> > > > > > > > > Let's say a user started a compute with fut = >> >> >> >> > > > > compute.runAsync(task); >> >> >> >> > > > > > > and >> >> >> >> > > > > > > > > now calls fut.complete(someVal); Does this mean >> >> >> >> > > > > > > > > that >> >> >> >> > > > > > > > > Ignite >> >> >> >> > no >> >> >> >> > > > > longer >> >> >> >> > > > > > > > needs >> >> >> >> > > > > > > > > to execute the task? If the task is currently >> >> running, >> >> >> >> > > > > > > > > does >> >> >> >> > it >> >> >> >> > > > need >> >> >> >> > > > > > to >> >> >> >> > > > > > > be >> >> >> >> > > > > > > > > canceled? >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > > Using CompletableFuture.anyOf() is a good >> >> >> >> > > > > > > > > instrument >> >> >> >> > > > > > > > > in >> >> >> >> this >> >> >> >> > > case >> >> >> >> > > > > > > because >> >> >> >> > > > > > > > > it makes the 'first future wins' contract >> >> >> >> > > > > > > > > explicit >> >> >> >> > > > > > > > > in >> >> >> the >> >> >> >> > code. >> >> >> >> > > > > > Besides >> >> >> >> > > > > > > > > that, the point regarding the cancel() method is >> >> >> >> > > > > > > > > valid, >> >> >> >> > > > > > > > > and >> >> >> >> > we >> >> >> >> > > > will >> >> >> >> > > > > > > need >> >> >> >> > > > > > > > > some custom mechanics to cancel a computation, >> >> >> >> > > > > > > > > so >> a >> >> >> >> > > > > > > > > custom >> >> >> >> > > > > interface >> >> >> >> > > > > > > that >> >> >> >> > > > > > > > > simply extends both Future and CompletableStage >> >> >> >> > > > > > > > > seems >> >> >> >> > > reasonable >> >> >> >> > > > to >> >> >> >> > > > > > me. >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > > --AG >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > > пн, 29 мар. 2021 г. в 09:12, Ivan Pavlukhin < >> >> >> >> > > vololo...@gmail.com >> >> >> >> > > > >: >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > > > Val, >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > There were enough hype around Reactive >> >> >> >> > > > > > > > > > programming >> >> >> past >> >> >> >> > > years. >> >> >> >> > > > I >> >> >> >> > > > > > > > > > remind a lot of talks about RxJava. And I >> suppose >> >> it >> >> >> >> worth >> >> >> >> > to >> >> >> >> > > > > > > consider >> >> >> >> > > > > > > > > > it. But it requires some time to study modern >> >> trends >> >> >> to >> >> >> >> > make >> >> >> >> > > a >> >> >> >> > > > > > > choice. >> >> >> >> > > > > > > > > > So far I am not ready to facilitate Reactive >> >> >> >> > > > > > > > > > API >> >> for >> >> >> >> Ignite >> >> >> >> > > 3. >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > Regarding CompletableFuture. >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > > The point is that currently a future >> >> >> >> > > > > > > > > > > returned >> >> from >> >> >> >> > > > > > > > > > > any >> >> >> >> of >> >> >> >> > > > > > Ignite's >> >> >> >> > > > > > > > > async >> >> >> >> > > > > > > > > > > operations is supposed to be completed with >> >> >> >> > > > > > > > > > > a >> >> >> >> > > > > > > > > > > value >> >> >> >> only >> >> >> >> > by >> >> >> >> > > > > > Ignite >> >> >> >> > > > > > > > > > itself, >> >> >> >> > > > > > > > > > > not by the user. If we follow the same >> approach >> >> in >> >> >> >> Ignite >> >> >> >> > > 3, >> >> >> >> > > > > > > > returning >> >> >> >> > > > > > > > > > > CompletableFuture is surely wrong in my >> >> >> >> > > > > > > > > > > view. >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > My first thoughts was similar. But later I >> >> >> >> > > > > > > > > > thought >> >> >> what >> >> >> >> > > > > > > > > > a >> >> >> >> > > user >> >> >> >> > > > > > would >> >> >> >> > > > > > > > > > like do with returned future. And one of cases >> >> >> >> > > > > > > > > > I >> >> >> >> > > > > > > > > > imagined >> >> >> >> > > was a >> >> >> >> > > > > > case >> >> >> >> > > > > > > > > > of alternative result. E.g. a user uses Ignite >> >> >> >> > > > > > > > > > and >> >> >> >> another >> >> >> >> > > data >> >> >> >> > > > > > > source >> >> >> >> > > > > > > > > > in his application. He wants to use a value >> >> >> >> > > > > > > > > > arrived >> >> >> >> faster. >> >> >> >> > > He >> >> >> >> > > > > > > > > > combines 2 futures like >> >> >> >> > > > > > > > > > CompletableFuture.anyOf(...). >> >> >> >> > > > > Consequently >> >> >> >> > > > > > > > > > even if we prohibit >> >> >> >> > > > > > > > > > CompletableFuture.complete(...) >> >> >> >> > > explicitly >> >> >> >> > > > > then >> >> >> >> > > > > > > it >> >> >> >> > > > > > > > > > will be possible to create a combination that >> >> >> >> > > > > > > > > > will >> >> >> >> > > > > > > > > > allow >> >> >> >> > > > > premature >> >> >> >> > > > > > > > > > future completion. After all generally >> >> >> >> > > > > > > > > > CompletableFuture >> >> >> >> > is a >> >> >> >> > > > > > > > > > placeholder for async computaion result and if >> >> >> >> > > > > > > > > > a >> >> >> >> > > > > > > > > > user >> >> >> >> wants >> >> >> >> > > to >> >> >> >> > > > > > > > > > substitute result returned from Ignite why >> should >> >> we >> >> >> >> > disallow >> >> >> >> > > > him >> >> >> >> > > > > > to >> >> >> >> > > > > > > > > > do it? >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > Also I found one more suspicious thing with >> >> >> >> > > CompletableFuture. >> >> >> >> > > > As >> >> >> >> > > > > > it >> >> >> >> > > > > > > > > > is a concrete class it implements a cancel() >> >> method. >> >> >> >> > > > > > > > > > And >> >> >> >> > as I >> >> >> >> > > > see >> >> >> >> > > > > > the >> >> >> >> > > > > > > > > > implementation does not try to cancel >> >> >> >> > > > > > > > > > underlying >> >> >> >> > > computations. >> >> >> >> > > > Is >> >> >> >> > > > > > not >> >> >> >> > > > > > > > > > it a problem? >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > 2021-03-29 7:30 GMT+03:00, Valentin Kulichenko >> >> >> >> > > > > > > > > > < >> >> >> >> > > > > > > > > > valentin.kuliche...@gmail.com>: >> >> >> >> > > > > > > > > > > Ivan, >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > It's not really about the "harm", but more >> >> >> >> > > > > > > > > > > about >> >> >> >> > > > > > > > > > > "what >> >> >> >> > > should >> >> >> >> > > > > we >> >> >> >> > > > > > do >> >> >> >> > > > > > > > if >> >> >> >> > > > > > > > > > this >> >> >> >> > > > > > > > > > > method is called?". Imagine the following >> code: >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > CompletableFuture<String> fut = >> >> >> >> > > > > > > > > > > cache.getAsync(key); >> >> >> >> > > > > > > > > > > fut.complete("something"); >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > What should happen in this case? >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > The point is that currently a future >> >> >> >> > > > > > > > > > > returned >> >> from >> >> >> >> > > > > > > > > > > any >> >> >> >> of >> >> >> >> > > > > > Ignite's >> >> >> >> > > > > > > > > async >> >> >> >> > > > > > > > > > > operations is supposed to be completed with >> >> >> >> > > > > > > > > > > a >> >> >> >> > > > > > > > > > > value >> >> >> >> only >> >> >> >> > by >> >> >> >> > > > > > Ignite >> >> >> >> > > > > > > > > > itself, >> >> >> >> > > > > > > > > > > not by the user. If we follow the same >> approach >> >> in >> >> >> >> Ignite >> >> >> >> > > 3, >> >> >> >> > > > > > > > returning >> >> >> >> > > > > > > > > > > CompletableFuture is surely wrong in my >> >> >> >> > > > > > > > > > > view. >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > At the same time, if we take a fundamentally >> >> >> >> > > > > > > > > > > different >> >> >> >> > > route >> >> >> >> > > > > with >> >> >> >> > > > > > > the >> >> >> >> > > > > > > > > > async >> >> >> >> > > > > > > > > > > APIs, this whole discussion might become >> >> >> >> > > > > > > > > > > irrelevant. >> >> >> >> For >> >> >> >> > > > > example, >> >> >> >> > > > > > > can >> >> >> >> > > > > > > > > you >> >> >> >> > > > > > > > > > > elaborate on your thinking around the >> >> >> >> > > > > > > > > > > reactive >> >> >> >> > > > > > > > > > > API? >> >> >> >> > > > > > > > > > > Do >> >> >> >> > you >> >> >> >> > > > have >> >> >> >> > > > > > any >> >> >> >> > > > > > > > > > > specifics in mind? >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > -Val >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > > On Sat, Mar 27, 2021 at 9:18 PM Ivan >> >> >> >> > > > > > > > > > > Pavlukhin >> >> >> >> > > > > > > > > > > < >> >> >> >> > > > > > > vololo...@gmail.com> >> >> >> >> > > > > > > > > > wrote: >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > >> > The methods below shouldn't be accessible >> >> >> >> > > > > > > > > > >> > for >> >> >> >> > > > > > > > > > >> > user: >> >> >> >> > > > > > > > > > >> > complete() >> >> >> >> > > > > > > > > > >> > completeExceptionaly() >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> Folks, in case of user-facing API, do you >> >> >> >> > > > > > > > > > >> think >> >> >> >> > > > > > > > > > >> there >> >> >> >> > is a >> >> >> >> > > > > real >> >> >> >> > > > > > > harm >> >> >> >> > > > > > > > > > >> in allowing a user to manually "complete" a >> >> >> >> > > > > > > > > > >> future? >> >> >> >> > > > > > > > > > >> I >> >> >> >> > > > suppose >> >> >> >> > > > > a >> >> >> >> > > > > > > user >> >> >> >> > > > > > > > > > >> employs some post-processing for future >> >> >> >> > > > > > > > > > >> results >> >> >> >> > > > > > > > > > >> and >> >> >> >> > > > > potentially >> >> >> >> > > > > > > > wants >> >> >> >> > > > > > > > > > >> to have control of these results as well. >> E.g. >> >> >> >> premature >> >> >> >> > > > > > > completion >> >> >> >> > > > > > > > in >> >> >> >> > > > > > > > > > >> case when a result is no longer needed is >> >> >> >> > > > > > > > > > >> possible >> >> >> >> > usage. >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> Also I thinkg it might be a good time to >> >> >> >> > > > > > > > > > >> ponder >> >> >> >> > > > > > > > > > >> about >> >> >> >> > > > > > > Future/Promise >> >> >> >> > > > > > > > > > >> APIs in general. Why such API is our >> >> >> >> > > > > > > > > > >> choice? >> >> >> >> > > > > > > > > > >> Can >> >> >> >> > > > > > > > > > >> we >> >> >> >> > choose >> >> >> >> > > > > e.g. >> >> >> >> > > > > > > > > > >> Reactive API style instead? >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> 2021-03-27 0:33 GMT+03:00, Valentin >> Kulichenko >> >> >> >> > > > > > > > > > >> < >> >> >> >> > > > > > > > > > >> valentin.kuliche...@gmail.com>: >> >> >> >> > > > > > > > > > >> > Andrey, >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> > I see. So in a nutshell, you're saying >> >> >> >> > > > > > > > > > >> > that >> >> >> >> > > > > > > > > > >> > we >> >> >> >> > > > > > > > > > >> > want >> >> >> >> to >> >> >> >> > > > > return >> >> >> >> > > > > > a >> >> >> >> > > > > > > > > future >> >> >> >> > > > > > > > > > >> that >> >> >> >> > > > > > > > > > >> > the user's code is not allowed to >> >> >> >> > > > > > > > > > >> > complete. >> >> >> >> > > > > > > > > > >> > In >> >> >> >> > > > > > > > > > >> > this >> >> >> >> > > case, >> >> >> >> > > > I >> >> >> >> > > > > > > think >> >> >> >> > > > > > > > > it's >> >> >> >> > > > > > > > > > >> > clear that CompletableFuture is not what >> >> >> >> > > > > > > > > > >> > we >> >> >> >> > > > > > > > > > >> > need. >> >> >> >> > > > > > > > > > >> > We >> >> >> >> > > > > actually >> >> >> >> > > > > > > > need a >> >> >> >> > > > > > > > > > >> > NonCompletableFuture :) >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> > My vote is for the custom interface. >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> > -Val >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> > On Fri, Mar 26, 2021 at 2:25 AM Andrey >> >> >> >> > > > > > > > > > >> > Mashenkov >> >> >> >> > > > > > > > > > >> > <andrey.mashen...@gmail.com> >> >> >> >> > > > > > > > > > >> > wrote: >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> >> Val, >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> The methods below shouldn't be >> >> >> >> > > > > > > > > > >> >> accessible >> >> >> >> > > > > > > > > > >> >> for >> >> >> >> > > > > > > > > > >> >> user: >> >> >> >> > > > > > > > > > >> >> complete() >> >> >> >> > > > > > > > > > >> >> completeExceptionaly() >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> Returning CompletableFuture we must >> >> >> >> > > > > > > > > > >> >> always >> >> >> >> > > > > > > > > > >> >> make >> >> >> a >> >> >> >> > copy >> >> >> >> > > to >> >> >> >> > > > > > > prevent >> >> >> >> > > > > > > > > the >> >> >> >> > > > > > > > > > >> >> original future from being completed by >> >> >> >> > > > > > > > > > >> >> mistake. >> >> >> >> > > > > > > > > > >> >> I think it will NOT be enough to do that >> >> >> returing >> >> >> >> the >> >> >> >> > > > > future >> >> >> >> > > > > > to >> >> >> >> > > > > > > > the >> >> >> >> > > > > > > > > > >> >> end-user, but from every critical module >> to >> >> >> >> > > > > > > > > > >> >> the >> >> >> >> > outside >> >> >> >> > > > of >> >> >> >> > > > > > the >> >> >> >> > > > > > > > > > module, >> >> >> >> > > > > > > > > > >> >> e.g. to plugins. The impact of >> >> >> >> > > > > > > > > > >> >> disclosing >> >> >> >> > > ExchangeFuture, >> >> >> >> > > > > > > > > > >> >> PartitionReleaseFuture to plugins may be >> >> >> serious. >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> IgniteFuture<T> extends Future<T>, >> >> >> >> CompletionStage<T> >> >> >> >> > > > which >> >> >> >> > > > > > > > > > >> >> implementation >> >> >> >> > > > > > > > > > >> >> will just wrap CompletableFuture these >> >> >> >> > > > > > > > > > >> >> issues >> >> >> >> > > > > > > > > > >> >> will >> >> >> >> be >> >> >> >> > > > > > resolved >> >> >> >> > > > > > > in >> >> >> >> > > > > > > > > > >> natural >> >> >> >> > > > > > > > > > >> >> way. >> >> >> >> > > > > > > > > > >> >> In addition we can force >> >> toCompletableFuture() >> >> >> >> method >> >> >> >> > > to >> >> >> >> > > > > > > return a >> >> >> >> > > > > > > > > > >> >> defensive >> >> >> >> > > > > > > > > > >> >> copy(), that resolves the last concern. >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> On Fri, Mar 26, 2021 at 11:38 AM >> Konstantin >> >> >> Orlov >> >> >> >> > > > > > > > > > >> >> <kor...@gridgain.com> >> >> >> >> > > > > > > > > > >> >> wrote: >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> > CompletableFuture seems a better >> >> >> >> > > > > > > > > > >> >> > option >> >> >> >> > > > > > > > > > >> >> > to >> >> >> >> > > > > > > > > > >> >> > me. >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > -- >> >> >> >> > > > > > > > > > >> >> > Regards, >> >> >> >> > > > > > > > > > >> >> > Konstantin Orlov >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > > On 26 Mar 2021, at 11:07, Pavel >> >> >> >> > > > > > > > > > >> >> > > Tupitsyn >> >> < >> >> >> >> > > > > > > > ptupit...@apache.org >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > >> >> > > wrote: >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > On the one hand, I agree with >> >> >> >> > > > > > > > > > >> >> > > Alexey. >> >> >> >> > > > > > > > > > >> >> > > CompletableFuture has complete* >> methods >> >> >> which >> >> >> >> > > should >> >> >> >> > > > > not >> >> >> >> > > > > > be >> >> >> >> > > > > > > > > > >> available >> >> >> >> > > > > > > > > > >> >> to >> >> >> >> > > > > > > > > > >> >> > > the user code. >> >> >> >> > > > > > > > > > >> >> > > This can be solved with a simple >> >> interface >> >> >> >> > > > > > > > > > >> >> > > like >> >> >> >> > we >> >> >> >> > > do >> >> >> >> > > > > in >> >> >> >> > > > > > > Thin >> >> >> >> > > > > > > > > > >> Client: >> >> >> >> > > > > > > > > > >> >> > > IgniteClientFuture<T> extends >> >> >> >> > > > > > > > > > >> >> > > Future<T>, >> >> >> >> > > > > > CompletionStage<T> >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > On the other hand: >> >> >> >> > > > > > > > > > >> >> > > - CompletionStage has >> >> >> >> > > > > > > > > > >> >> > > toCompletableFuture >> >> >> >> anyway >> >> >> >> > > > > (rather >> >> >> >> > > > > > > > weird) >> >> >> >> > > > > > > > > > >> >> > > - Other libraries use >> CompletableFuture >> >> >> >> > > > > > > > > > >> >> > > and >> >> >> >> > > > > > > > > > >> >> > > it >> >> >> >> > > seems >> >> >> >> > > > to >> >> >> >> > > > > > be >> >> >> >> > > > > > > > fine >> >> >> >> > > > > > > > > > >> >> > > - Using CompletableFuture is the >> >> >> >> > > > > > > > > > >> >> > > simplest >> >> >> >> > approach >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > So I lean towards CompletableFuture >> >> >> >> > > > > > > > > > >> >> > > too. >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > > On Fri, Mar 26, 2021 at 10:46 AM >> Alexey >> >> >> >> > Kukushkin < >> >> >> >> > > > > > > > > > >> >> > kukushkinale...@gmail.com> >> >> >> >> > > > > > > > > > >> >> > > wrote: >> >> >> >> > > > > > > > > > >> >> > > >> >> >> >> > > > > > > > > > >> >> > >> I do not like Java's >> CompletableFuture >> >> >> >> > > > > > > > > > >> >> > >> and >> >> >> >> > prefer >> >> >> >> > > > our >> >> >> >> > > > > > own >> >> >> >> > > > > > > > > Future >> >> >> >> > > > > > > > > > >> >> > (revised >> >> >> >> > > > > > > > > > >> >> > >> IgniteFuture). >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> My understanding of the Future (or >> >> >> >> > > > > > > > > > >> >> > >> Promise) >> >> >> >> > > pattern >> >> >> >> > > > in >> >> >> >> > > > > > > > general >> >> >> >> > > > > > > > > > is >> >> >> >> > > > > > > > > > >> >> having >> >> >> >> > > > > > > > > > >> >> > >> two separate APIs: >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> 1. Server-side: create, set >> >> >> >> > > > > > > > > > >> >> > >> result, >> >> >> >> > > > > > > > > > >> >> > >> raise >> >> >> >> > error, >> >> >> >> > > > > > cancel >> >> >> >> > > > > > > > from >> >> >> >> > > > > > > > > > >> >> > >> server. >> >> >> >> > > > > > > > > > >> >> > >> 2. Client-side: get result, >> >> >> >> > > > > > > > > > >> >> > >> handle >> >> >> >> > > > > > > > > > >> >> > >> error, >> >> >> >> > cancel >> >> >> >> > > > > from >> >> >> >> > > > > > > > client >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> Java's CompletableFuture looks like >> >> >> >> > > > > > > > > > >> >> > >> both >> >> >> the >> >> >> >> > > > > client-side >> >> >> >> > > > > > > and >> >> >> >> > > > > > > > > > >> >> > >> server-side API. The "Completeable" >> >> >> >> > > > > > > > > > >> >> > >> prefix >> >> >> >> > > > > > > > > > >> >> > >> in >> >> >> >> > the >> >> >> >> > > > name >> >> >> >> > > > > > is >> >> >> >> > > > > > > > > > already >> >> >> >> > > > > > > > > > >> >> > confusing >> >> >> >> > > > > > > > > > >> >> > >> for a client since it cannot >> >> >> >> > > > > > > > > > >> >> > >> "complete" >> >> >> >> > > > > > > > > > >> >> > >> an >> >> >> >> > > > operation, >> >> >> >> > > > > > > only a >> >> >> >> > > > > > > > > > >> >> > >> server >> >> >> >> > > > > > > > > > >> >> can. >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> I would create our own IgniteFuture >> >> >> >> > > > > > > > > > >> >> > >> adding >> >> >> >> > > > client-side >> >> >> >> > > > > > > > > > >> functionality >> >> >> >> > > > > > > > > > >> >> we >> >> >> >> > > > > > > > > > >> >> > >> currently miss (like client-side >> >> >> >> cancellation). >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> пт, 26 мар. 2021 г. в 01:08, >> >> >> >> > > > > > > > > > >> >> > >> Valentin >> >> >> >> > Kulichenko < >> >> >> >> > > > > > > > > > >> >> > >> valentin.kuliche...@gmail.com>: >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >>> Andrey, >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >>> Can you compile a full list of >> >> >> >> > > > > > > > > > >> >> > >>> these >> >> >> >> > > > > > > > > > >> >> > >>> risky >> >> >> >> > > methods, >> >> >> >> > > > > and >> >> >> >> > > > > > > > > > >> >> > >>> elaborate >> >> >> >> > > > > > > > > > >> >> > >>> on >> >> >> >> > > > > > > > > > >> >> > what >> >> >> >> > > > > > > > > > >> >> > >>> the risks are? >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >>> Generally, CompletableFuture is a >> >> >> >> > > > > > > > > > >> >> > >>> much >> >> >> >> > > > > > > > > > >> >> > >>> better >> >> >> >> > > > option, >> >> >> >> > > > > > > > because >> >> >> >> > > > > > > > > > >> >> > >>> it's >> >> >> >> > > > > > > > > > >> >> > >>> standard. But we need to make sure >> it >> >> >> >> actually >> >> >> >> > > fits >> >> >> >> > > > > our >> >> >> >> > > > > > > > needs >> >> >> >> > > > > > > > > > >> >> > >>> and >> >> >> >> > > > > > > > > > >> >> > doesn't >> >> >> >> > > > > > > > > > >> >> > >>> do more harm than good. >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >>> -Val >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >>> On Thu, Mar 25, 2021 at 12:23 PM >> >> >> >> > > > > > > > > > >> >> > >>> Alexei >> >> >> >> > > Scherbakov >> >> >> >> > > > < >> >> >> >> > > > > > > > > > >> >> > >>> alexey.scherbak...@gmail.com> >> wrote: >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >>>> I think both options are fine, >> >> >> >> > > > > > > > > > >> >> > >>>> but >> >> >> >> personally >> >> >> >> > > lean >> >> >> >> > > > > > > toward >> >> >> >> > > > > > > > > > >> >> > >>>> CompletableFuture. >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>>> чт, 25 мар. 2021 г. в 17:56, Atri >> >> >> >> > > > > > > > > > >> >> > >>>> Sharma >> >> >> < >> >> >> >> > > > > > > a...@apache.org >> >> >> >> > > > > > > > >: >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> I would suggest using >> >> >> >> > > > > > > > > > >> >> > >>>>> CompletableFuture >> >> >> >> > > > > > > > > > >> >> > >>>>> -- >> >> >> >> I >> >> >> >> > > > don't >> >> >> >> > > > > > see >> >> >> >> > > > > > > a >> >> >> >> > > > > > > > > need >> >> >> >> > > > > > > > > > >> for >> >> >> >> > > > > > > > > > >> >> > >>>>> a >> >> >> >> > > > > > > > > > >> >> > >>>> custom >> >> >> >> > > > > > > > > > >> >> > >>>>> interface that is unique to us. >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> It also allows a lower barrier >> >> >> >> > > > > > > > > > >> >> > >>>>> for >> >> new >> >> >> >> > > > contributors >> >> >> >> > > > > > for >> >> >> >> > > > > > > > > > >> >> understanding >> >> >> >> > > > > > > > > > >> >> > >>>>> existing code >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> On Thu, 25 Mar 2021, 20:18 >> >> >> >> > > > > > > > > > >> >> > >>>>> Andrey >> >> >> >> Mashenkov, >> >> >> >> > < >> >> >> >> > > > > > > > > > >> >> > >>> andrey.mashen...@gmail.com >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> wrote: >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> Hi Igniters, >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> I'd like to start a discussion >> >> >> >> > > > > > > > > > >> >> > >>>>>> about >> >> >> >> > replacing >> >> >> >> > > > our >> >> >> >> > > > > > > > custom >> >> >> >> > > > > > > > > > >> >> > >>> IgniteFuture >> >> >> >> > > > > > > > > > >> >> > >>>>>> class with CompletableFuture - >> >> >> >> > > > > > > > > > >> >> > >>>>>> existed >> >> >> >> > > > > > > > > > >> >> > >>>>>> JDK >> >> >> >> > > class >> >> >> >> > > > > > > > > > >> >> > >>>>>> or rework it's implementation >> >> >> >> > > > > > > > > > >> >> > >>>>>> (like >> >> >> some >> >> >> >> > other >> >> >> >> > > > > > > products >> >> >> >> > > > > > > > > > done) >> >> >> >> > > > > > > > > > >> to >> >> >> >> > > > > > > > > > >> >> > >>>>>> a >> >> >> >> > > > > > > > > > >> >> > >>>>>> composition of CompletionStage >> and >> >> >> >> > > > > > > > > > >> >> > >>>>>> Future >> >> >> >> > > > > > interfaces. >> >> >> >> > > > > > > > > > >> >> > >>>>>> or maybe other option if you >> >> >> >> > > > > > > > > > >> >> > >>>>>> have >> >> any >> >> >> >> ideas. >> >> >> >> > > Do >> >> >> >> > > > > you? >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> 1. The first approach pros and >> >> >> >> > > > > > > > > > >> >> > >>>>>> cons >> >> >> >> > > > > > > > > > >> >> > >>>>>> are >> >> >> >> > > > > > > > > > >> >> > >>>>>> + Well-known JDK class >> >> >> >> > > > > > > > > > >> >> > >>>>>> + Already implemented >> >> >> >> > > > > > > > > > >> >> > >>>>>> - It is a class, not an >> interface. >> >> >> >> > > > > > > > > > >> >> > >>>>>> - Expose some potentially >> >> >> >> > > > > > > > > > >> >> > >>>>>> harmful >> >> >> >> > > > > > > > > > >> >> > >>>>>> methods >> >> >> >> > like >> >> >> >> > > > > > > > > "complete()". >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> On the other side, it has >> >> >> >> > > > > > > > > > >> >> > >>>>>> copy() >> >> >> >> > > > > > > > > > >> >> > >>>>>> method >> >> >> >> > > > > > > > > > >> >> > >>>>>> to >> >> >> >> > > > create >> >> >> >> > > > > > > > > defensive >> >> >> >> > > > > > > > > > >> copy >> >> >> >> > > > > > > > > > >> >> > >> and >> >> >> >> > > > > > > > > > >> >> > >>>>>> minimalCompletionStage() to >> >> >> >> > > > > > > > > > >> >> > >>>>>> restrict >> >> >> >> harmful >> >> >> >> > > > > method >> >> >> >> > > > > > > > usage. >> >> >> >> > > > > > > > > > >> >> > >>>>>> Thus, this look like an >> applicable >> >> >> >> solution, >> >> >> >> > > but >> >> >> >> > > > > we >> >> >> >> > > > > > > > should >> >> >> >> > > > > > > > > > be >> >> >> >> > > > > > > > > > >> >> > >> careful >> >> >> >> > > > > > > > > > >> >> > >>>>>> exposing internal future to the >> >> >> outside. >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> 2. The second approach is to >> >> >> >> > > > > > > > > > >> >> > >>>>>> implement >> >> >> >> > > > > > > > > > >> >> > >>>>>> our >> >> >> >> > own >> >> >> >> > > > > > > interface >> >> >> >> > > > > > > > > > like >> >> >> >> > > > > > > > > > >> >> > >>>>>> the >> >> >> >> > > > > > > > > > >> >> > >>> next >> >> >> >> > > > > > > > > > >> >> > >>>>> one: >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> interface IgniteFuture<T> >> >> >> >> > > > > > > > > > >> >> > >>>>>> extends >> >> >> >> > > > > > CompletableStage<T>, >> >> >> >> > > > > > > > > > >> Future<T> >> >> >> >> > > > > > > > > > >> >> > >>>>>> { >> >> >> >> > > > > > > > > > >> >> > >>>>>> } >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> Pros and cons are >> >> >> >> > > > > > > > > > >> >> > >>>>>> + Our interfaces/classes >> contracts >> >> >> >> > > > > > > > > > >> >> > >>>>>> will >> >> >> >> > expose >> >> >> >> > > > an >> >> >> >> > > > > > > > > interface >> >> >> >> > > > > > > > > > >> >> > >>>>>> rather >> >> >> >> > > > > > > > > > >> >> > >>> than >> >> >> >> > > > > > > > > > >> >> > >>>>>> concrete implementation. >> >> >> >> > > > > > > > > > >> >> > >>>>>> + All methods are safe. >> >> >> >> > > > > > > > > > >> >> > >>>>>> - Some implementation is >> required. >> >> >> >> > > > > > > > > > >> >> > >>>>>> - CompletableStage has a method >> >> >> >> > > > > > toCompletableFuture() >> >> >> >> > > > > > > > and >> >> >> >> > > > > > > > > > can >> >> >> >> > > > > > > > > > >> be >> >> >> >> > > > > > > > > > >> >> > >>>>> converted >> >> >> >> > > > > > > > > > >> >> > >>>>>> to CompletableFuture. This >> >> >> >> > > > > > > > > > >> >> > >>>>>> should >> >> >> >> > > > > > > > > > >> >> > >>>>>> be >> >> >> >> > > supported. >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> However, we still could wrap >> >> >> >> > CompletableFuture >> >> >> >> > > > and >> >> >> >> > > > > > > don't >> >> >> >> > > > > > > > > > >> >> > >>>>>> bother >> >> >> >> > > > > > > > > > >> >> > >> about >> >> >> >> > > > > > > > > > >> >> > >>>>>> creating a defensive copy. >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> Other project experience: >> >> >> >> > > > > > > > > > >> >> > >>>>>> * Spotify uses >> >> >> >> > > > > > > > > > >> >> > >>>>>> CompletableFuture >> >> >> >> > > > > > > > > > >> >> > >>>>>> directly >> >> >> >> > [1]. >> >> >> >> > > > > > > > > > >> >> > >>>>>> * Redis goes the second >> >> >> >> > > > > > > > > > >> >> > >>>>>> approach >> >> >> >> > > > > > > > > > >> >> > >>>>>> [2] >> >> >> >> > > > > > > > > > >> >> > >>>>>> * Vertx explicitly extends >> >> >> >> CompletableFuture >> >> >> >> > > > [3]. >> >> >> >> > > > > > > > However, >> >> >> >> > > > > > > > > > >> >> > >>>>>> they >> >> >> >> > > > > > > > > > >> >> > >> have >> >> >> >> > > > > > > > > > >> >> > >>>>> custom >> >> >> >> > > > > > > > > > >> >> > >>>>>> future classes and a number of >> >> >> >> > > > > > > > > > >> >> > >>>>>> helpers >> >> >> >> that >> >> >> >> > > > could >> >> >> >> > > > > be >> >> >> >> > > > > > > > > > replaced >> >> >> >> > > > > > > > > > >> >> > >>>>>> with >> >> >> >> > > > > > > > > > >> >> > >>>>>> CompletableStage. Maybe it is >> just >> >> >> >> > > > > > > > > > >> >> > >>>>>> a >> >> >> >> > legacy.' >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> Any thoughts? >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> [1] >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > >> >> >> >> > > > > > >> >> >> >> > > > > >> >> >> >> > > > >> >> >> >> > > >> >> >> >> > >> >> >> >> >> >> >> >> >> >> https://spotify.github.io/completable-futures/apidocs/com/spotify/futures/ConcurrencyReducer.html >> >> >> >> > > > > > > > > > >> >> > >>>>>> [2] >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > >> >> >> >> > > > > > >> >> >> >> > > > > >> >> >> >> > > > >> >> >> >> > > >> >> >> >> > >> >> >> >> >> >> >> >> >> >> https://lettuce.io/lettuce-4/release/api/com/lambdaworks/redis/RedisFuture.html >> >> >> >> > > > > > > > > > >> >> > >>>>>> [3] >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > >> >> >> >> > > > > > >> >> >> >> > > > > >> >> >> >> > > > >> >> >> >> > > >> >> >> >> > >> >> >> >> >> >> >> >> >> >> https://javadoc.io/static/org.jspare.vertx/vertx-jspare/1.1.0-M03/org/jspare/vertx/concurrent/VertxCompletableFuture.html >> >> >> >> > > > > > > > > > >> >> > >>>>>> -- >> >> >> >> > > > > > > > > > >> >> > >>>>>> Best regards, >> >> >> >> > > > > > > > > > >> >> > >>>>>> Andrey V. Mashenkov >> >> >> >> > > > > > > > > > >> >> > >>>>>> >> >> >> >> > > > > > > > > > >> >> > >>>>> >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>>> -- >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>>> Best regards, >> >> >> >> > > > > > > > > > >> >> > >>>> Alexei Scherbakov >> >> >> >> > > > > > > > > > >> >> > >>>> >> >> >> >> > > > > > > > > > >> >> > >>> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> -- >> >> >> >> > > > > > > > > > >> >> > >> Best regards, >> >> >> >> > > > > > > > > > >> >> > >> Alexey >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> > >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> >> -- >> >> >> >> > > > > > > > > > >> >> Best regards, >> >> >> >> > > > > > > > > > >> >> Andrey V. Mashenkov >> >> >> >> > > > > > > > > > >> >> >> >> >> >> > > > > > > > > > >> > >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> -- >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > >> Best regards, >> >> >> >> > > > > > > > > > >> Ivan Pavlukhin >> >> >> >> > > > > > > > > > >> >> >> >> >> > > > > > > > > > > >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > -- >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > > Best regards, >> >> >> >> > > > > > > > > > Ivan Pavlukhin >> >> >> >> > > > > > > > > > >> >> >> >> > > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > >> >> >> >> > > > > > > > -- >> >> >> >> > > > > > > > Best regards, >> >> >> >> > > > > > > > Andrey V. Mashenkov >> >> >> >> > > > > > > > >> >> >> >> > > > > > > >> >> >> >> > > > > > -- >> >> >> >> > > > > > Regards, >> >> >> >> > > > > > >> >> >> >> > > > > > Atri >> >> >> >> > > > > > Apache Concerted >> >> >> >> > > > > > >> >> >> >> > > > > >> >> >> >> > > > >> >> >> >> > > >> >> >> >> > >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> >> Best regards, >> >> >> >> Andrey V. Mashenkov >> >> >> >> >> >> >> > >> >> >> >> >> >> >> >> >> -- >> >> >> >> >> >> Best regards, >> >> >> Ivan Pavlukhin >> >> >> >> >> >> >> >> > >> >> > -- >> >> > Best regards, >> >> > Andrey V. Mashenkov >> >> > >> >> >> >> >> >> -- >> >> >> >> Best regards, >> >> Ivan Pavlukhin >> >> >> >> >> > >> > -- >> > Best regards, >> > Andrey V. Mashenkov >> > >> >> >> -- >> >> Best regards, >> Ivan Pavlukhin >> >> > > -- > Best regards, > Andrey V. Mashenkov > -- Best regards, Ivan Pavlukhin