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