You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ignite.apache.org by Vladimir Ozerov <vo...@gridgain.com> on 2015/10/09 15:47:28 UTC

.Net: separate methods for async operations.

Igniters,

Some time ago we decided to merge sync and async methods. E.g. instead of
...

interface Cache<K, V> {
    V get(K key);
    Future<V> getAsync(K key);
}

... we now have:

interface Cache<K, V> extends AsyncSupport {
    V get(K key);
    Cache withAsync();

    Future lastFuture(); // From AsyncSupport, returns future for the last
operation.
}

This approach is questionable. Less methods is good, and all methods go
through JCache API. But async mode became more complex and less usable.
This is especially obvious in Java 8 with its lambdas and CompletableFuture.

In .Net we blindly applied this approach as well. But in this world
AsyncSupport gives even less advantages than in Java:
1) There is no JCache spec here;
2) Core .Net API very often use paired sync and async operations in the
same class near each other - DoMethod(), DoMethodAsync() - and this is what
users normally expect from async-enabled classes.
3) [AsyncSupported] attribute is not highlighted in Visual Studio. The only
way to understand that method supports async mode is to install ReSharper
or to look into source code.
4) .Net has native continuations support with async/await keywords. Our API
doesn't support it well.

Having said that I want to return paired "async" operations to .Net API:
interface ICache<K, V> {
    V Get(K key);
    IFuture<V> GetAsync(K key);
}

It will add 25 new methods to ICache interface and remove 2. But API will
become much more friendly and natural for .Net users.

Any thoughts/objections?

Vladimir.

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
On Tue, Oct 13, 2015 at 1:54 AM, Pavel Tupitsyn <pt...@gridgain.com>
wrote:

> > I disagree here. I think consistency matters.
> > Moreover, based on the previous .NET examples you have provided, I do not
> see much difference between .NET and Java, other than different syntax
>
> What really matters is consistency with the rest of .NET platform. There
> are clear design guidelines:
> https://msdn.microsoft.com/en-us/library/hh873175(v=vs.110).aspx
> These guidelines are followed throughout standard APIs. Everyone is used to
> them.
>

Why can't we have both, parity in API and good design? I think .NET will be
slightly different, but overall, the AsyncCache approach which is being
discussed should work, no?

Really, there is no need to invent anything. It won't be better. "When
> in Rome, do as the Romans do".
>

Given that we are adding native support for Java, C#, and C++, we are
bigger than Rome already. We should be creating something like European
Union :)


>
> Thanks,
>
>
> On Tue, Oct 13, 2015 at 8:56 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > Dima,
> >
> > I do not like JSR 107 v1.1 approach. First, it is not user friendly.
> > Second, it is prone to deadlock/starvation problems we are currently
> > discussing in another thread because these "Collectors" are continuations
> > essentially.
> >
> > On Tue, Oct 13, 2015 at 12:42 AM, Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >
> > wrote:
> >
> > > I just took a look at JSR 107, and looks like they are taking a
> different
> > > (in my view not as elegant) route:
> > >
> > >
> >
> https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java
> > >
> > > Any thoughts on this?
> > >
> > > D.
> > >
> > > On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <
> vozerov@gridgain.com>
> > > wrote:
> > >
> > > > Well, if we asume that the most common usage will be
> > > > IgniteCache.async().doSomething(), then yes - backwards
> transformation
> > is
> > > > not necessary.
> > > >
> > > > All in all this approach seems to be the most clean among other
> > > suggested.
> > > >
> > > > On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <
> > > sergi.vladykin@gmail.com>
> > > > wrote:
> > > >
> > > > > Dmitriy,
> > > > >
> > > > > I mostly agree with your points except naming and hierarchy:
> > > > >
> > > > > 1. I don't like CacheAsync, it is ugly.
> > > > >
> > > > > 2. If IgniteCache extends AsyncCache then we can't use the same
> names
> > > for
> > > > > methods, we will be forced to use *blaAsync(...)* format
> > > > > which is ugly for me as well. Also this will pollute sync API with
> > > async
> > > > > one, while we are trying to avoid that.
> > > > >
> > > > > Sergi
> > > > >
> > > > > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >:
> > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com>
> > > > > > wrote:
> > > > > >
> > > > > >
> > > > > > > The problem with this approach is that not all methods are
> async.
> > > > E.g.
> > > > > > > name(), lock(K), iterator(), etc.. So you should either mix
> sync
> > > and
> > > > > > async
> > > > > > > methods in AsyncCache still, or expose only async methods.
> > > > > >
> > > > > >
> > > > > > I think AsyncCache, or rather CacheAsync, should expose only
> async
> > > > > methods.
> > > > > > Moreover, should IgniteCache simply extend CacheAsync API?
> > > > > >
> > > > > >
> > > > > > > In the latter case we will require backwards
> > > > > > > transformation: IgniteCache AsyncCache.sync().
> > > > > > >
> > > > > >
> > > > > > Not sure this is needed.
> > > > > >
> > > > > >
> > > > > > > Consistency between platforms should have minimal priority.
> .Net
> > > and
> > > > > Java
> > > > > > > are very different. For example we cannot even have "V Get(K)"
> > > method
> > > > > in
> > > > > > > .Net cache. Instead we have "V TryGet(K, out bool)" because
> .Net
> > > > > supports
> > > > > > > structs and have full generics support and naive Java approach
> > > simply
> > > > > > > doesn't work here. Base concepts must be the same across
> > platforms,
> > > > but
> > > > > > > methods signatures and grouping will be different.
> > > > > > >
> > > > > >
> > > > > > I disagree here. I think consistency matters. Moreover, based on
> > the
> > > > > > previous .NET examples you have provided, I do not see much
> > > difference
> > > > > > between .NET and Java, other than different syntax. I think the
> > same
> > > > > > CacheAsync design can be applied to both.
> > > > > >
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > > > > sergi.vladykin@gmail.com>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > In my view we should not pollute sync APIs with all async
> > > methods,
> > > > > > > > definitely we have to separate them
> > > > > > > > for better UX.
> > > > > > > >
> > > > > > > > Currently on Java we have IgniteAsyncSupport with method
> > > > withAsync()
> > > > > > > which
> > > > > > > > returns the same sync API
> > > > > > > > but that API works in broken manner. Instead it should look
> > like
> > > > the
> > > > > > > > following IMO
> > > > > > > >
> > > > > > > > interface AsyncSupport<X> {
> > > > > > > >     X async();
> > > > > > > > }
> > > > > > > >
> > > > > > > > Where X will be an interface with respective async API.  For
> > > > example
> > > > > > for
> > > > > > > > IngneCache we will have AsyncCache
> > > > > > > > with all the respective async variants of all methods. Like
> > this
> > > > > > > >
> > > > > > > > interface IgniteCache<K,V> extends
> > AsyncSupport<AsyncCache<K,V>>
> > > {
> > > > > > > >     V get(K key);
> > > > > > > > }
> > > > > > > >
> > > > > > > >
> > > > > > > > interface AsyncCache<K,V> {
> > > > > > > >     IgniteFuture<V> get(K key);
> > > > > > > > }
> > > > > > > >
> > > > > > > > From implementation standpoint both interfaces can be
> > implemented
> > > > by
> > > > > > the
> > > > > > > > same class but for user API
> > > > > > > > they will be conveniently separated. Implementation of every
> > sync
> > > > > > method
> > > > > > > is
> > > > > > > > trivial if we have
> > > > > > > > async counterpart: just call get() on received future.
> > > > > > > >
> > > > > > > > From documentation point of view we just have to write on
> each
> > > > method
> > > > > > > that
> > > > > > > > it is a async variant of some
> > > > > > > > method on main API like following:
> > > > > > > >
> > > > > > > >    /**
> > > > > > > >      * Asynchronous variant of method {@link
> > > > > IgniteCache#get(Object)}.
> > > > > > > >      */
> > > > > > > >
> > > > > > > > This way we will not need to maintain the same docs for all
> > sync
> > > > and
> > > > > > > async
> > > > > > > > methods.
> > > > > > > >
> > > > > > > > Sorry, I'm not an expert in .Net but I believe this approach
> > will
> > > > fit
> > > > > > > .Net
> > > > > > > > as well, so it can be consistent across platforms.
> > > > > > > >
> > > > > > > > Sergi
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> > > > dsetrakyan@apache.org
> > > > > >:
> > > > > > > >
> > > > > > > > > Do I understand correctly that you are suggesting adding
> > > > > "Async(..)"
> > > > > > > > > counterparts for all the synchronous methods?
> > > > > > > > >
> > > > > > > > > Are there any objections about this? If we do it in .NET,
> > then
> > > we
> > > > > > might
> > > > > > > > as
> > > > > > > > > well do it in Java, because in my view the same reasoning
> can
> > > be
> > > > > made
> > > > > > > for
> > > > > > > > > Java. This will cause significant proliferation of Async
> > > methods.
> > > > > For
> > > > > > > > > example just on IgniteCache API, we will have to add about
> 40
> > > > > Async()
> > > > > > > > > methods.
> > > > > > > > >
> > > > > > > > > D.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > > > > vozerov@gridgain.com
> > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > No. "await" is actually return from the method
> immediately.
> > > Let
> > > > > me
> > > > > > > show
> > > > > > > > > it
> > > > > > > > > > again:
> > > > > > > > > >
> > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > > > > >
> > > > > > > > > >     await res;
> > > > > > > > > >
> > > > > > > > > >     return res.Result * res.Result;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > maps to the following pseudo-code in Java:
> > > > > > > > > >
> > > > > > > > > > Future<Integer> getAndMultiply() {
> > > > > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > > > > >
> > > > > > > > > >     return res.chain((f) => {
> > > > > > > > > >         return f.get() * f.get();
> > > > > > > > > >     });
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > > > > yzhdanov@apache.org>
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > > completed
> > > > > > in
> > > > > > > > > > > parallel thread?
> > > > > > > > > > >
> > > > > > > > > > > --Yakov
> > > > > > > > > > >
> > > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >:
> > > > > > > > > > >
> > > > > > > > > > > > Example with Get() operation:
> > > > > > > > > > > >
> > > > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > > > >     // This line is executed in current thread.
> > > > > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > > > > >
> > > > > > > > > > > >     await res;
> > > > > > > > > > > >
> > > > > > > > > > > >     // This code is executed in another thread when
> res
> > > is
> > > > > > ready.
> > > > > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > > > > >
> > > > > > > > > > > >     return mul;
> > > > > > > > > > > > }
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > > > > dsetrakyan@apache.org
> > > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > > vozerov@gridgain.com
> > > > > > > > > > > >
> > > > > > > > > > > > > wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > > Guys, let's try keeping this topic focused on
> .Net
> > > > > please,
> > > > > > > > > because
> > > > > > > > > > > the
> > > > > > > > > > > > > > product is not released yet and we can create any
> > API
> > > > we
> > > > > > > like.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Dima, answering your question about async/await -
> > > this
> > > > is
> > > > > > > > > actually
> > > > > > > > > > > > native
> > > > > > > > > > > > > > continuation support in .Net. Consider the
> > following
> > > > .Net
> > > > > > > > method:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > > > > >
> > > > > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > > > > }
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > And what if the method putAsync would return a
> value.
> > > How
> > > > > > would
> > > > > > > > > this
> > > > > > > > > > > code
> > > > > > > > > > > > > change?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
>
>
> --
> --
> Pavel Tupitsyn
> GridGain Systems, Inc.
> www.gridgain.com
>

Re: .Net: separate methods for async operations.

Posted by Pavel Tupitsyn <pt...@gridgain.com>.
> I disagree here. I think consistency matters.
> Moreover, based on the previous .NET examples you have provided, I do not
see much difference between .NET and Java, other than different syntax

What really matters is consistency with the rest of .NET platform. There
are clear design guidelines:
https://msdn.microsoft.com/en-us/library/hh873175(v=vs.110).aspx
These guidelines are followed throughout standard APIs. Everyone is used to
them.

Really, there is no need to invent anything. It won't be better. "When in
Rome, do as the Romans do".

Thanks,


On Tue, Oct 13, 2015 at 8:56 AM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> Dima,
>
> I do not like JSR 107 v1.1 approach. First, it is not user friendly.
> Second, it is prone to deadlock/starvation problems we are currently
> discussing in another thread because these "Collectors" are continuations
> essentially.
>
> On Tue, Oct 13, 2015 at 12:42 AM, Dmitriy Setrakyan <dsetrakyan@apache.org
> >
> wrote:
>
> > I just took a look at JSR 107, and looks like they are taking a different
> > (in my view not as elegant) route:
> >
> >
> https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java
> >
> > Any thoughts on this?
> >
> > D.
> >
> > On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > Well, if we asume that the most common usage will be
> > > IgniteCache.async().doSomething(), then yes - backwards transformation
> is
> > > not necessary.
> > >
> > > All in all this approach seems to be the most clean among other
> > suggested.
> > >
> > > On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <
> > sergi.vladykin@gmail.com>
> > > wrote:
> > >
> > > > Dmitriy,
> > > >
> > > > I mostly agree with your points except naming and hierarchy:
> > > >
> > > > 1. I don't like CacheAsync, it is ugly.
> > > >
> > > > 2. If IgniteCache extends AsyncCache then we can't use the same names
> > for
> > > > methods, we will be forced to use *blaAsync(...)* format
> > > > which is ugly for me as well. Also this will pollute sync API with
> > async
> > > > one, while we are trying to avoid that.
> > > >
> > > > Sergi
> > > >
> > > > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <dsetrakyan@apache.org
> >:
> > > >
> > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com>
> > > > > wrote:
> > > > >
> > > > >
> > > > > > The problem with this approach is that not all methods are async.
> > > E.g.
> > > > > > name(), lock(K), iterator(), etc.. So you should either mix sync
> > and
> > > > > async
> > > > > > methods in AsyncCache still, or expose only async methods.
> > > > >
> > > > >
> > > > > I think AsyncCache, or rather CacheAsync, should expose only async
> > > > methods.
> > > > > Moreover, should IgniteCache simply extend CacheAsync API?
> > > > >
> > > > >
> > > > > > In the latter case we will require backwards
> > > > > > transformation: IgniteCache AsyncCache.sync().
> > > > > >
> > > > >
> > > > > Not sure this is needed.
> > > > >
> > > > >
> > > > > > Consistency between platforms should have minimal priority. .Net
> > and
> > > > Java
> > > > > > are very different. For example we cannot even have "V Get(K)"
> > method
> > > > in
> > > > > > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net
> > > > supports
> > > > > > structs and have full generics support and naive Java approach
> > simply
> > > > > > doesn't work here. Base concepts must be the same across
> platforms,
> > > but
> > > > > > methods signatures and grouping will be different.
> > > > > >
> > > > >
> > > > > I disagree here. I think consistency matters. Moreover, based on
> the
> > > > > previous .NET examples you have provided, I do not see much
> > difference
> > > > > between .NET and Java, other than different syntax. I think the
> same
> > > > > CacheAsync design can be applied to both.
> > > > >
> > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > > > sergi.vladykin@gmail.com>
> > > > > > wrote:
> > > > > >
> > > > > > > In my view we should not pollute sync APIs with all async
> > methods,
> > > > > > > definitely we have to separate them
> > > > > > > for better UX.
> > > > > > >
> > > > > > > Currently on Java we have IgniteAsyncSupport with method
> > > withAsync()
> > > > > > which
> > > > > > > returns the same sync API
> > > > > > > but that API works in broken manner. Instead it should look
> like
> > > the
> > > > > > > following IMO
> > > > > > >
> > > > > > > interface AsyncSupport<X> {
> > > > > > >     X async();
> > > > > > > }
> > > > > > >
> > > > > > > Where X will be an interface with respective async API.  For
> > > example
> > > > > for
> > > > > > > IngneCache we will have AsyncCache
> > > > > > > with all the respective async variants of all methods. Like
> this
> > > > > > >
> > > > > > > interface IgniteCache<K,V> extends
> AsyncSupport<AsyncCache<K,V>>
> > {
> > > > > > >     V get(K key);
> > > > > > > }
> > > > > > >
> > > > > > >
> > > > > > > interface AsyncCache<K,V> {
> > > > > > >     IgniteFuture<V> get(K key);
> > > > > > > }
> > > > > > >
> > > > > > > From implementation standpoint both interfaces can be
> implemented
> > > by
> > > > > the
> > > > > > > same class but for user API
> > > > > > > they will be conveniently separated. Implementation of every
> sync
> > > > > method
> > > > > > is
> > > > > > > trivial if we have
> > > > > > > async counterpart: just call get() on received future.
> > > > > > >
> > > > > > > From documentation point of view we just have to write on each
> > > method
> > > > > > that
> > > > > > > it is a async variant of some
> > > > > > > method on main API like following:
> > > > > > >
> > > > > > >    /**
> > > > > > >      * Asynchronous variant of method {@link
> > > > IgniteCache#get(Object)}.
> > > > > > >      */
> > > > > > >
> > > > > > > This way we will not need to maintain the same docs for all
> sync
> > > and
> > > > > > async
> > > > > > > methods.
> > > > > > >
> > > > > > > Sorry, I'm not an expert in .Net but I believe this approach
> will
> > > fit
> > > > > > .Net
> > > > > > > as well, so it can be consistent across platforms.
> > > > > > >
> > > > > > > Sergi
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> > > dsetrakyan@apache.org
> > > > >:
> > > > > > >
> > > > > > > > Do I understand correctly that you are suggesting adding
> > > > "Async(..)"
> > > > > > > > counterparts for all the synchronous methods?
> > > > > > > >
> > > > > > > > Are there any objections about this? If we do it in .NET,
> then
> > we
> > > > > might
> > > > > > > as
> > > > > > > > well do it in Java, because in my view the same reasoning can
> > be
> > > > made
> > > > > > for
> > > > > > > > Java. This will cause significant proliferation of Async
> > methods.
> > > > For
> > > > > > > > example just on IgniteCache API, we will have to add about 40
> > > > Async()
> > > > > > > > methods.
> > > > > > > >
> > > > > > > > D.
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > No. "await" is actually return from the method immediately.
> > Let
> > > > me
> > > > > > show
> > > > > > > > it
> > > > > > > > > again:
> > > > > > > > >
> > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > > > >
> > > > > > > > >     await res;
> > > > > > > > >
> > > > > > > > >     return res.Result * res.Result;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > maps to the following pseudo-code in Java:
> > > > > > > > >
> > > > > > > > > Future<Integer> getAndMultiply() {
> > > > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > > > >
> > > > > > > > >     return res.chain((f) => {
> > > > > > > > >         return f.get() * f.get();
> > > > > > > > >     });
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > > > yzhdanov@apache.org>
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > completed
> > > > > in
> > > > > > > > > > parallel thread?
> > > > > > > > > >
> > > > > > > > > > --Yakov
> > > > > > > > > >
> > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >:
> > > > > > > > > >
> > > > > > > > > > > Example with Get() operation:
> > > > > > > > > > >
> > > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > > >     // This line is executed in current thread.
> > > > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > > > >
> > > > > > > > > > >     await res;
> > > > > > > > > > >
> > > > > > > > > > >     // This code is executed in another thread when res
> > is
> > > > > ready.
> > > > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > > > >
> > > > > > > > > > >     return mul;
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > > > dsetrakyan@apache.org
> > > > > > > > > > > >
> > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > vozerov@gridgain.com
> > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > Guys, let's try keeping this topic focused on .Net
> > > > please,
> > > > > > > > because
> > > > > > > > > > the
> > > > > > > > > > > > > product is not released yet and we can create any
> API
> > > we
> > > > > > like.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Dima, answering your question about async/await -
> > this
> > > is
> > > > > > > > actually
> > > > > > > > > > > native
> > > > > > > > > > > > > continuation support in .Net. Consider the
> following
> > > .Net
> > > > > > > method:
> > > > > > > > > > > > >
> > > > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > > > >
> > > > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > > > }
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > And what if the method putAsync would return a value.
> > How
> > > > > would
> > > > > > > > this
> > > > > > > > > > code
> > > > > > > > > > > > change?
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>



-- 
-- 
Pavel Tupitsyn
GridGain Systems, Inc.
www.gridgain.com

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
> Do we have a choice here? We will have to implement JSR107 anyway. Let's
> just make sure that whatever approach we come up with does not contradict
> JSR107 functionality.

As I understand from JSR107 mailing list, nobodody really understand what
the next version will be about. For now they are focused on maintenance
release and async operations are not planned here. Some event is planned at
the end of October at JavaOne which should boost further discussions.

As for async methods you mentioned, they were submitted recently into a
separate branch by Greg Luck and it is neither design draft, neither
proposed solution. Just some code without any official status.


On Tue, Oct 13, 2015 at 12:14 PM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> On Mon, Oct 12, 2015 at 10:56 PM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > Dima,
> >
> > I do not like JSR 107 v1.1 approach. First, it is not user friendly.
> > Second, it is prone to deadlock/starvation problems we are currently
> > discussing in another thread because these "Collectors" are continuations
> > essentially.
> >
>
> Do we have a choice here? We will have to implement JSR107 anyway. Let's
> just make sure that whatever approach we come up with does not contradict
> JSR107 functionality.
>
>
> >
> > On Tue, Oct 13, 2015 at 12:42 AM, Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >
> > wrote:
> >
> > > I just took a look at JSR 107, and looks like they are taking a
> different
> > > (in my view not as elegant) route:
> > >
> > >
> >
> https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java
> > >
> > > Any thoughts on this?
> > >
> > > D.
> > >
> > > On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <
> vozerov@gridgain.com>
> > > wrote:
> > >
> > > > Well, if we asume that the most common usage will be
> > > > IgniteCache.async().doSomething(), then yes - backwards
> transformation
> > is
> > > > not necessary.
> > > >
> > > > All in all this approach seems to be the most clean among other
> > > suggested.
> > > >
> > > > On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <
> > > sergi.vladykin@gmail.com>
> > > > wrote:
> > > >
> > > > > Dmitriy,
> > > > >
> > > > > I mostly agree with your points except naming and hierarchy:
> > > > >
> > > > > 1. I don't like CacheAsync, it is ugly.
> > > > >
> > > > > 2. If IgniteCache extends AsyncCache then we can't use the same
> names
> > > for
> > > > > methods, we will be forced to use *blaAsync(...)* format
> > > > > which is ugly for me as well. Also this will pollute sync API with
> > > async
> > > > > one, while we are trying to avoid that.
> > > > >
> > > > > Sergi
> > > > >
> > > > > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >:
> > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com>
> > > > > > wrote:
> > > > > >
> > > > > >
> > > > > > > The problem with this approach is that not all methods are
> async.
> > > > E.g.
> > > > > > > name(), lock(K), iterator(), etc.. So you should either mix
> sync
> > > and
> > > > > > async
> > > > > > > methods in AsyncCache still, or expose only async methods.
> > > > > >
> > > > > >
> > > > > > I think AsyncCache, or rather CacheAsync, should expose only
> async
> > > > > methods.
> > > > > > Moreover, should IgniteCache simply extend CacheAsync API?
> > > > > >
> > > > > >
> > > > > > > In the latter case we will require backwards
> > > > > > > transformation: IgniteCache AsyncCache.sync().
> > > > > > >
> > > > > >
> > > > > > Not sure this is needed.
> > > > > >
> > > > > >
> > > > > > > Consistency between platforms should have minimal priority.
> .Net
> > > and
> > > > > Java
> > > > > > > are very different. For example we cannot even have "V Get(K)"
> > > method
> > > > > in
> > > > > > > .Net cache. Instead we have "V TryGet(K, out bool)" because
> .Net
> > > > > supports
> > > > > > > structs and have full generics support and naive Java approach
> > > simply
> > > > > > > doesn't work here. Base concepts must be the same across
> > platforms,
> > > > but
> > > > > > > methods signatures and grouping will be different.
> > > > > > >
> > > > > >
> > > > > > I disagree here. I think consistency matters. Moreover, based on
> > the
> > > > > > previous .NET examples you have provided, I do not see much
> > > difference
> > > > > > between .NET and Java, other than different syntax. I think the
> > same
> > > > > > CacheAsync design can be applied to both.
> > > > > >
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > > > > sergi.vladykin@gmail.com>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > In my view we should not pollute sync APIs with all async
> > > methods,
> > > > > > > > definitely we have to separate them
> > > > > > > > for better UX.
> > > > > > > >
> > > > > > > > Currently on Java we have IgniteAsyncSupport with method
> > > > withAsync()
> > > > > > > which
> > > > > > > > returns the same sync API
> > > > > > > > but that API works in broken manner. Instead it should look
> > like
> > > > the
> > > > > > > > following IMO
> > > > > > > >
> > > > > > > > interface AsyncSupport<X> {
> > > > > > > >     X async();
> > > > > > > > }
> > > > > > > >
> > > > > > > > Where X will be an interface with respective async API.  For
> > > > example
> > > > > > for
> > > > > > > > IngneCache we will have AsyncCache
> > > > > > > > with all the respective async variants of all methods. Like
> > this
> > > > > > > >
> > > > > > > > interface IgniteCache<K,V> extends
> > AsyncSupport<AsyncCache<K,V>>
> > > {
> > > > > > > >     V get(K key);
> > > > > > > > }
> > > > > > > >
> > > > > > > >
> > > > > > > > interface AsyncCache<K,V> {
> > > > > > > >     IgniteFuture<V> get(K key);
> > > > > > > > }
> > > > > > > >
> > > > > > > > From implementation standpoint both interfaces can be
> > implemented
> > > > by
> > > > > > the
> > > > > > > > same class but for user API
> > > > > > > > they will be conveniently separated. Implementation of every
> > sync
> > > > > > method
> > > > > > > is
> > > > > > > > trivial if we have
> > > > > > > > async counterpart: just call get() on received future.
> > > > > > > >
> > > > > > > > From documentation point of view we just have to write on
> each
> > > > method
> > > > > > > that
> > > > > > > > it is a async variant of some
> > > > > > > > method on main API like following:
> > > > > > > >
> > > > > > > >    /**
> > > > > > > >      * Asynchronous variant of method {@link
> > > > > IgniteCache#get(Object)}.
> > > > > > > >      */
> > > > > > > >
> > > > > > > > This way we will not need to maintain the same docs for all
> > sync
> > > > and
> > > > > > > async
> > > > > > > > methods.
> > > > > > > >
> > > > > > > > Sorry, I'm not an expert in .Net but I believe this approach
> > will
> > > > fit
> > > > > > > .Net
> > > > > > > > as well, so it can be consistent across platforms.
> > > > > > > >
> > > > > > > > Sergi
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> > > > dsetrakyan@apache.org
> > > > > >:
> > > > > > > >
> > > > > > > > > Do I understand correctly that you are suggesting adding
> > > > > "Async(..)"
> > > > > > > > > counterparts for all the synchronous methods?
> > > > > > > > >
> > > > > > > > > Are there any objections about this? If we do it in .NET,
> > then
> > > we
> > > > > > might
> > > > > > > > as
> > > > > > > > > well do it in Java, because in my view the same reasoning
> can
> > > be
> > > > > made
> > > > > > > for
> > > > > > > > > Java. This will cause significant proliferation of Async
> > > methods.
> > > > > For
> > > > > > > > > example just on IgniteCache API, we will have to add about
> 40
> > > > > Async()
> > > > > > > > > methods.
> > > > > > > > >
> > > > > > > > > D.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > > > > vozerov@gridgain.com
> > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > No. "await" is actually return from the method
> immediately.
> > > Let
> > > > > me
> > > > > > > show
> > > > > > > > > it
> > > > > > > > > > again:
> > > > > > > > > >
> > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > > > > >
> > > > > > > > > >     await res;
> > > > > > > > > >
> > > > > > > > > >     return res.Result * res.Result;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > maps to the following pseudo-code in Java:
> > > > > > > > > >
> > > > > > > > > > Future<Integer> getAndMultiply() {
> > > > > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > > > > >
> > > > > > > > > >     return res.chain((f) => {
> > > > > > > > > >         return f.get() * f.get();
> > > > > > > > > >     });
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > > > > yzhdanov@apache.org>
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > > completed
> > > > > > in
> > > > > > > > > > > parallel thread?
> > > > > > > > > > >
> > > > > > > > > > > --Yakov
> > > > > > > > > > >
> > > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >:
> > > > > > > > > > >
> > > > > > > > > > > > Example with Get() operation:
> > > > > > > > > > > >
> > > > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > > > >     // This line is executed in current thread.
> > > > > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > > > > >
> > > > > > > > > > > >     await res;
> > > > > > > > > > > >
> > > > > > > > > > > >     // This code is executed in another thread when
> res
> > > is
> > > > > > ready.
> > > > > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > > > > >
> > > > > > > > > > > >     return mul;
> > > > > > > > > > > > }
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > > > > dsetrakyan@apache.org
> > > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > > vozerov@gridgain.com
> > > > > > > > > > > >
> > > > > > > > > > > > > wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > > Guys, let's try keeping this topic focused on
> .Net
> > > > > please,
> > > > > > > > > because
> > > > > > > > > > > the
> > > > > > > > > > > > > > product is not released yet and we can create any
> > API
> > > > we
> > > > > > > like.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Dima, answering your question about async/await -
> > > this
> > > > is
> > > > > > > > > actually
> > > > > > > > > > > > native
> > > > > > > > > > > > > > continuation support in .Net. Consider the
> > following
> > > > .Net
> > > > > > > > method:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > > > > >
> > > > > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > > > > }
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > And what if the method putAsync would return a
> value.
> > > How
> > > > > > would
> > > > > > > > > this
> > > > > > > > > > > code
> > > > > > > > > > > > > change?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
On Mon, Oct 12, 2015 at 10:56 PM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> Dima,
>
> I do not like JSR 107 v1.1 approach. First, it is not user friendly.
> Second, it is prone to deadlock/starvation problems we are currently
> discussing in another thread because these "Collectors" are continuations
> essentially.
>

Do we have a choice here? We will have to implement JSR107 anyway. Let's
just make sure that whatever approach we come up with does not contradict
JSR107 functionality.


>
> On Tue, Oct 13, 2015 at 12:42 AM, Dmitriy Setrakyan <dsetrakyan@apache.org
> >
> wrote:
>
> > I just took a look at JSR 107, and looks like they are taking a different
> > (in my view not as elegant) route:
> >
> >
> https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java
> >
> > Any thoughts on this?
> >
> > D.
> >
> > On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > Well, if we asume that the most common usage will be
> > > IgniteCache.async().doSomething(), then yes - backwards transformation
> is
> > > not necessary.
> > >
> > > All in all this approach seems to be the most clean among other
> > suggested.
> > >
> > > On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <
> > sergi.vladykin@gmail.com>
> > > wrote:
> > >
> > > > Dmitriy,
> > > >
> > > > I mostly agree with your points except naming and hierarchy:
> > > >
> > > > 1. I don't like CacheAsync, it is ugly.
> > > >
> > > > 2. If IgniteCache extends AsyncCache then we can't use the same names
> > for
> > > > methods, we will be forced to use *blaAsync(...)* format
> > > > which is ugly for me as well. Also this will pollute sync API with
> > async
> > > > one, while we are trying to avoid that.
> > > >
> > > > Sergi
> > > >
> > > > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <dsetrakyan@apache.org
> >:
> > > >
> > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com>
> > > > > wrote:
> > > > >
> > > > >
> > > > > > The problem with this approach is that not all methods are async.
> > > E.g.
> > > > > > name(), lock(K), iterator(), etc.. So you should either mix sync
> > and
> > > > > async
> > > > > > methods in AsyncCache still, or expose only async methods.
> > > > >
> > > > >
> > > > > I think AsyncCache, or rather CacheAsync, should expose only async
> > > > methods.
> > > > > Moreover, should IgniteCache simply extend CacheAsync API?
> > > > >
> > > > >
> > > > > > In the latter case we will require backwards
> > > > > > transformation: IgniteCache AsyncCache.sync().
> > > > > >
> > > > >
> > > > > Not sure this is needed.
> > > > >
> > > > >
> > > > > > Consistency between platforms should have minimal priority. .Net
> > and
> > > > Java
> > > > > > are very different. For example we cannot even have "V Get(K)"
> > method
> > > > in
> > > > > > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net
> > > > supports
> > > > > > structs and have full generics support and naive Java approach
> > simply
> > > > > > doesn't work here. Base concepts must be the same across
> platforms,
> > > but
> > > > > > methods signatures and grouping will be different.
> > > > > >
> > > > >
> > > > > I disagree here. I think consistency matters. Moreover, based on
> the
> > > > > previous .NET examples you have provided, I do not see much
> > difference
> > > > > between .NET and Java, other than different syntax. I think the
> same
> > > > > CacheAsync design can be applied to both.
> > > > >
> > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > > > sergi.vladykin@gmail.com>
> > > > > > wrote:
> > > > > >
> > > > > > > In my view we should not pollute sync APIs with all async
> > methods,
> > > > > > > definitely we have to separate them
> > > > > > > for better UX.
> > > > > > >
> > > > > > > Currently on Java we have IgniteAsyncSupport with method
> > > withAsync()
> > > > > > which
> > > > > > > returns the same sync API
> > > > > > > but that API works in broken manner. Instead it should look
> like
> > > the
> > > > > > > following IMO
> > > > > > >
> > > > > > > interface AsyncSupport<X> {
> > > > > > >     X async();
> > > > > > > }
> > > > > > >
> > > > > > > Where X will be an interface with respective async API.  For
> > > example
> > > > > for
> > > > > > > IngneCache we will have AsyncCache
> > > > > > > with all the respective async variants of all methods. Like
> this
> > > > > > >
> > > > > > > interface IgniteCache<K,V> extends
> AsyncSupport<AsyncCache<K,V>>
> > {
> > > > > > >     V get(K key);
> > > > > > > }
> > > > > > >
> > > > > > >
> > > > > > > interface AsyncCache<K,V> {
> > > > > > >     IgniteFuture<V> get(K key);
> > > > > > > }
> > > > > > >
> > > > > > > From implementation standpoint both interfaces can be
> implemented
> > > by
> > > > > the
> > > > > > > same class but for user API
> > > > > > > they will be conveniently separated. Implementation of every
> sync
> > > > > method
> > > > > > is
> > > > > > > trivial if we have
> > > > > > > async counterpart: just call get() on received future.
> > > > > > >
> > > > > > > From documentation point of view we just have to write on each
> > > method
> > > > > > that
> > > > > > > it is a async variant of some
> > > > > > > method on main API like following:
> > > > > > >
> > > > > > >    /**
> > > > > > >      * Asynchronous variant of method {@link
> > > > IgniteCache#get(Object)}.
> > > > > > >      */
> > > > > > >
> > > > > > > This way we will not need to maintain the same docs for all
> sync
> > > and
> > > > > > async
> > > > > > > methods.
> > > > > > >
> > > > > > > Sorry, I'm not an expert in .Net but I believe this approach
> will
> > > fit
> > > > > > .Net
> > > > > > > as well, so it can be consistent across platforms.
> > > > > > >
> > > > > > > Sergi
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> > > dsetrakyan@apache.org
> > > > >:
> > > > > > >
> > > > > > > > Do I understand correctly that you are suggesting adding
> > > > "Async(..)"
> > > > > > > > counterparts for all the synchronous methods?
> > > > > > > >
> > > > > > > > Are there any objections about this? If we do it in .NET,
> then
> > we
> > > > > might
> > > > > > > as
> > > > > > > > well do it in Java, because in my view the same reasoning can
> > be
> > > > made
> > > > > > for
> > > > > > > > Java. This will cause significant proliferation of Async
> > methods.
> > > > For
> > > > > > > > example just on IgniteCache API, we will have to add about 40
> > > > Async()
> > > > > > > > methods.
> > > > > > > >
> > > > > > > > D.
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > No. "await" is actually return from the method immediately.
> > Let
> > > > me
> > > > > > show
> > > > > > > > it
> > > > > > > > > again:
> > > > > > > > >
> > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > > > >
> > > > > > > > >     await res;
> > > > > > > > >
> > > > > > > > >     return res.Result * res.Result;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > maps to the following pseudo-code in Java:
> > > > > > > > >
> > > > > > > > > Future<Integer> getAndMultiply() {
> > > > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > > > >
> > > > > > > > >     return res.chain((f) => {
> > > > > > > > >         return f.get() * f.get();
> > > > > > > > >     });
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > > > yzhdanov@apache.org>
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > completed
> > > > > in
> > > > > > > > > > parallel thread?
> > > > > > > > > >
> > > > > > > > > > --Yakov
> > > > > > > > > >
> > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >:
> > > > > > > > > >
> > > > > > > > > > > Example with Get() operation:
> > > > > > > > > > >
> > > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > > >     // This line is executed in current thread.
> > > > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > > > >
> > > > > > > > > > >     await res;
> > > > > > > > > > >
> > > > > > > > > > >     // This code is executed in another thread when res
> > is
> > > > > ready.
> > > > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > > > >
> > > > > > > > > > >     return mul;
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > > > dsetrakyan@apache.org
> > > > > > > > > > > >
> > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > vozerov@gridgain.com
> > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > Guys, let's try keeping this topic focused on .Net
> > > > please,
> > > > > > > > because
> > > > > > > > > > the
> > > > > > > > > > > > > product is not released yet and we can create any
> API
> > > we
> > > > > > like.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Dima, answering your question about async/await -
> > this
> > > is
> > > > > > > > actually
> > > > > > > > > > > native
> > > > > > > > > > > > > continuation support in .Net. Consider the
> following
> > > .Net
> > > > > > > method:
> > > > > > > > > > > > >
> > > > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > > > >
> > > > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > > > }
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > And what if the method putAsync would return a value.
> > How
> > > > > would
> > > > > > > > this
> > > > > > > > > > code
> > > > > > > > > > > > change?
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Dima,

I do not like JSR 107 v1.1 approach. First, it is not user friendly.
Second, it is prone to deadlock/starvation problems we are currently
discussing in another thread because these "Collectors" are continuations
essentially.

On Tue, Oct 13, 2015 at 12:42 AM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> I just took a look at JSR 107, and looks like they are taking a different
> (in my view not as elegant) route:
>
> https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java
>
> Any thoughts on this?
>
> D.
>
> On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > Well, if we asume that the most common usage will be
> > IgniteCache.async().doSomething(), then yes - backwards transformation is
> > not necessary.
> >
> > All in all this approach seems to be the most clean among other
> suggested.
> >
> > On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <
> sergi.vladykin@gmail.com>
> > wrote:
> >
> > > Dmitriy,
> > >
> > > I mostly agree with your points except naming and hierarchy:
> > >
> > > 1. I don't like CacheAsync, it is ugly.
> > >
> > > 2. If IgniteCache extends AsyncCache then we can't use the same names
> for
> > > methods, we will be forced to use *blaAsync(...)* format
> > > which is ugly for me as well. Also this will pollute sync API with
> async
> > > one, while we are trying to avoid that.
> > >
> > > Sergi
> > >
> > > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> > >
> > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > vozerov@gridgain.com>
> > > > wrote:
> > > >
> > > >
> > > > > The problem with this approach is that not all methods are async.
> > E.g.
> > > > > name(), lock(K), iterator(), etc.. So you should either mix sync
> and
> > > > async
> > > > > methods in AsyncCache still, or expose only async methods.
> > > >
> > > >
> > > > I think AsyncCache, or rather CacheAsync, should expose only async
> > > methods.
> > > > Moreover, should IgniteCache simply extend CacheAsync API?
> > > >
> > > >
> > > > > In the latter case we will require backwards
> > > > > transformation: IgniteCache AsyncCache.sync().
> > > > >
> > > >
> > > > Not sure this is needed.
> > > >
> > > >
> > > > > Consistency between platforms should have minimal priority. .Net
> and
> > > Java
> > > > > are very different. For example we cannot even have "V Get(K)"
> method
> > > in
> > > > > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net
> > > supports
> > > > > structs and have full generics support and naive Java approach
> simply
> > > > > doesn't work here. Base concepts must be the same across platforms,
> > but
> > > > > methods signatures and grouping will be different.
> > > > >
> > > >
> > > > I disagree here. I think consistency matters. Moreover, based on the
> > > > previous .NET examples you have provided, I do not see much
> difference
> > > > between .NET and Java, other than different syntax. I think the same
> > > > CacheAsync design can be applied to both.
> > > >
> > > >
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > > sergi.vladykin@gmail.com>
> > > > > wrote:
> > > > >
> > > > > > In my view we should not pollute sync APIs with all async
> methods,
> > > > > > definitely we have to separate them
> > > > > > for better UX.
> > > > > >
> > > > > > Currently on Java we have IgniteAsyncSupport with method
> > withAsync()
> > > > > which
> > > > > > returns the same sync API
> > > > > > but that API works in broken manner. Instead it should look like
> > the
> > > > > > following IMO
> > > > > >
> > > > > > interface AsyncSupport<X> {
> > > > > >     X async();
> > > > > > }
> > > > > >
> > > > > > Where X will be an interface with respective async API.  For
> > example
> > > > for
> > > > > > IngneCache we will have AsyncCache
> > > > > > with all the respective async variants of all methods. Like this
> > > > > >
> > > > > > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>>
> {
> > > > > >     V get(K key);
> > > > > > }
> > > > > >
> > > > > >
> > > > > > interface AsyncCache<K,V> {
> > > > > >     IgniteFuture<V> get(K key);
> > > > > > }
> > > > > >
> > > > > > From implementation standpoint both interfaces can be implemented
> > by
> > > > the
> > > > > > same class but for user API
> > > > > > they will be conveniently separated. Implementation of every sync
> > > > method
> > > > > is
> > > > > > trivial if we have
> > > > > > async counterpart: just call get() on received future.
> > > > > >
> > > > > > From documentation point of view we just have to write on each
> > method
> > > > > that
> > > > > > it is a async variant of some
> > > > > > method on main API like following:
> > > > > >
> > > > > >    /**
> > > > > >      * Asynchronous variant of method {@link
> > > IgniteCache#get(Object)}.
> > > > > >      */
> > > > > >
> > > > > > This way we will not need to maintain the same docs for all sync
> > and
> > > > > async
> > > > > > methods.
> > > > > >
> > > > > > Sorry, I'm not an expert in .Net but I believe this approach will
> > fit
> > > > > .Net
> > > > > > as well, so it can be consistent across platforms.
> > > > > >
> > > > > > Sergi
> > > > > >
> > > > > >
> > > > > >
> > > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> > dsetrakyan@apache.org
> > > >:
> > > > > >
> > > > > > > Do I understand correctly that you are suggesting adding
> > > "Async(..)"
> > > > > > > counterparts for all the synchronous methods?
> > > > > > >
> > > > > > > Are there any objections about this? If we do it in .NET, then
> we
> > > > might
> > > > > > as
> > > > > > > well do it in Java, because in my view the same reasoning can
> be
> > > made
> > > > > for
> > > > > > > Java. This will cause significant proliferation of Async
> methods.
> > > For
> > > > > > > example just on IgniteCache API, we will have to add about 40
> > > Async()
> > > > > > > methods.
> > > > > > >
> > > > > > > D.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > No. "await" is actually return from the method immediately.
> Let
> > > me
> > > > > show
> > > > > > > it
> > > > > > > > again:
> > > > > > > >
> > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > > >
> > > > > > > >     await res;
> > > > > > > >
> > > > > > > >     return res.Result * res.Result;
> > > > > > > > }
> > > > > > > >
> > > > > > > > maps to the following pseudo-code in Java:
> > > > > > > >
> > > > > > > > Future<Integer> getAndMultiply() {
> > > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > > >
> > > > > > > >     return res.chain((f) => {
> > > > > > > >         return f.get() * f.get();
> > > > > > > >     });
> > > > > > > > }
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > > yzhdanov@apache.org>
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > Is current thread blocked until "await" instruction is
> > > completed
> > > > in
> > > > > > > > > parallel thread?
> > > > > > > > >
> > > > > > > > > --Yakov
> > > > > > > > >
> > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > vozerov@gridgain.com
> > > > >:
> > > > > > > > >
> > > > > > > > > > Example with Get() operation:
> > > > > > > > > >
> > > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > > >     // This line is executed in current thread.
> > > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > > >
> > > > > > > > > >     await res;
> > > > > > > > > >
> > > > > > > > > >     // This code is executed in another thread when res
> is
> > > > ready.
> > > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > > >
> > > > > > > > > >     return mul;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > > dsetrakyan@apache.org
> > > > > > > > > > >
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > vozerov@gridgain.com
> > > > > > > > > >
> > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > Guys, let's try keeping this topic focused on .Net
> > > please,
> > > > > > > because
> > > > > > > > > the
> > > > > > > > > > > > product is not released yet and we can create any API
> > we
> > > > > like.
> > > > > > > > > > > >
> > > > > > > > > > > > Dima, answering your question about async/await -
> this
> > is
> > > > > > > actually
> > > > > > > > > > native
> > > > > > > > > > > > continuation support in .Net. Consider the following
> > .Net
> > > > > > method:
> > > > > > > > > > > >
> > > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > > >
> > > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > > }
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > And what if the method putAsync would return a value.
> How
> > > > would
> > > > > > > this
> > > > > > > > > code
> > > > > > > > > > > change?
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
I just took a look at JSR 107, and looks like they are taking a different
(in my view not as elegant) route:
https://github.com/jsr107/jsr107spec/blob/async/src/main/java/javax/cache/Cache.java

Any thoughts on this?

D.

On Mon, Oct 12, 2015 at 11:11 AM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> Well, if we asume that the most common usage will be
> IgniteCache.async().doSomething(), then yes - backwards transformation is
> not necessary.
>
> All in all this approach seems to be the most clean among other suggested.
>
> On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > Dmitriy,
> >
> > I mostly agree with your points except naming and hierarchy:
> >
> > 1. I don't like CacheAsync, it is ugly.
> >
> > 2. If IgniteCache extends AsyncCache then we can't use the same names for
> > methods, we will be forced to use *blaAsync(...)* format
> > which is ugly for me as well. Also this will pollute sync API with async
> > one, while we are trying to avoid that.
> >
> > Sergi
> >
> > 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> vozerov@gridgain.com>
> > > wrote:
> > >
> > >
> > > > The problem with this approach is that not all methods are async.
> E.g.
> > > > name(), lock(K), iterator(), etc.. So you should either mix sync and
> > > async
> > > > methods in AsyncCache still, or expose only async methods.
> > >
> > >
> > > I think AsyncCache, or rather CacheAsync, should expose only async
> > methods.
> > > Moreover, should IgniteCache simply extend CacheAsync API?
> > >
> > >
> > > > In the latter case we will require backwards
> > > > transformation: IgniteCache AsyncCache.sync().
> > > >
> > >
> > > Not sure this is needed.
> > >
> > >
> > > > Consistency between platforms should have minimal priority. .Net and
> > Java
> > > > are very different. For example we cannot even have "V Get(K)" method
> > in
> > > > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net
> > supports
> > > > structs and have full generics support and naive Java approach simply
> > > > doesn't work here. Base concepts must be the same across platforms,
> but
> > > > methods signatures and grouping will be different.
> > > >
> > >
> > > I disagree here. I think consistency matters. Moreover, based on the
> > > previous .NET examples you have provided, I do not see much difference
> > > between .NET and Java, other than different syntax. I think the same
> > > CacheAsync design can be applied to both.
> > >
> > >
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > > sergi.vladykin@gmail.com>
> > > > wrote:
> > > >
> > > > > In my view we should not pollute sync APIs with all async methods,
> > > > > definitely we have to separate them
> > > > > for better UX.
> > > > >
> > > > > Currently on Java we have IgniteAsyncSupport with method
> withAsync()
> > > > which
> > > > > returns the same sync API
> > > > > but that API works in broken manner. Instead it should look like
> the
> > > > > following IMO
> > > > >
> > > > > interface AsyncSupport<X> {
> > > > >     X async();
> > > > > }
> > > > >
> > > > > Where X will be an interface with respective async API.  For
> example
> > > for
> > > > > IngneCache we will have AsyncCache
> > > > > with all the respective async variants of all methods. Like this
> > > > >
> > > > > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> > > > >     V get(K key);
> > > > > }
> > > > >
> > > > >
> > > > > interface AsyncCache<K,V> {
> > > > >     IgniteFuture<V> get(K key);
> > > > > }
> > > > >
> > > > > From implementation standpoint both interfaces can be implemented
> by
> > > the
> > > > > same class but for user API
> > > > > they will be conveniently separated. Implementation of every sync
> > > method
> > > > is
> > > > > trivial if we have
> > > > > async counterpart: just call get() on received future.
> > > > >
> > > > > From documentation point of view we just have to write on each
> method
> > > > that
> > > > > it is a async variant of some
> > > > > method on main API like following:
> > > > >
> > > > >    /**
> > > > >      * Asynchronous variant of method {@link
> > IgniteCache#get(Object)}.
> > > > >      */
> > > > >
> > > > > This way we will not need to maintain the same docs for all sync
> and
> > > > async
> > > > > methods.
> > > > >
> > > > > Sorry, I'm not an expert in .Net but I believe this approach will
> fit
> > > > .Net
> > > > > as well, so it can be consistent across platforms.
> > > > >
> > > > > Sergi
> > > > >
> > > > >
> > > > >
> > > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >:
> > > > >
> > > > > > Do I understand correctly that you are suggesting adding
> > "Async(..)"
> > > > > > counterparts for all the synchronous methods?
> > > > > >
> > > > > > Are there any objections about this? If we do it in .NET, then we
> > > might
> > > > > as
> > > > > > well do it in Java, because in my view the same reasoning can be
> > made
> > > > for
> > > > > > Java. This will cause significant proliferation of Async methods.
> > For
> > > > > > example just on IgniteCache API, we will have to add about 40
> > Async()
> > > > > > methods.
> > > > > >
> > > > > > D.
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com
> > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > No. "await" is actually return from the method immediately. Let
> > me
> > > > show
> > > > > > it
> > > > > > > again:
> > > > > > >
> > > > > > > async Task<int> GetAndMultiply() {
> > > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > > >
> > > > > > >     await res;
> > > > > > >
> > > > > > >     return res.Result * res.Result;
> > > > > > > }
> > > > > > >
> > > > > > > maps to the following pseudo-code in Java:
> > > > > > >
> > > > > > > Future<Integer> getAndMultiply() {
> > > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > > >
> > > > > > >     return res.chain((f) => {
> > > > > > >         return f.get() * f.get();
> > > > > > >     });
> > > > > > > }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > > yzhdanov@apache.org>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Is current thread blocked until "await" instruction is
> > completed
> > > in
> > > > > > > > parallel thread?
> > > > > > > >
> > > > > > > > --Yakov
> > > > > > > >
> > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > vozerov@gridgain.com
> > > >:
> > > > > > > >
> > > > > > > > > Example with Get() operation:
> > > > > > > > >
> > > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > > >     // This line is executed in current thread.
> > > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > > >
> > > > > > > > >     await res;
> > > > > > > > >
> > > > > > > > >     // This code is executed in another thread when res is
> > > ready.
> > > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > > >
> > > > > > > > >     return mul;
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > > dsetrakyan@apache.org
> > > > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > vozerov@gridgain.com
> > > > > > > > >
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Guys, let's try keeping this topic focused on .Net
> > please,
> > > > > > because
> > > > > > > > the
> > > > > > > > > > > product is not released yet and we can create any API
> we
> > > > like.
> > > > > > > > > > >
> > > > > > > > > > > Dima, answering your question about async/await - this
> is
> > > > > > actually
> > > > > > > > > native
> > > > > > > > > > > continuation support in .Net. Consider the following
> .Net
> > > > > method:
> > > > > > > > > > >
> > > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > > >
> > > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > And what if the method putAsync would return a value. How
> > > would
> > > > > > this
> > > > > > > > code
> > > > > > > > > > change?
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Well, if we asume that the most common usage will be
IgniteCache.async().doSomething(), then yes - backwards transformation is
not necessary.

All in all this approach seems to be the most clean among other suggested.

On Mon, Oct 12, 2015 at 8:38 PM, Sergi Vladykin <se...@gmail.com>
wrote:

> Dmitriy,
>
> I mostly agree with your points except naming and hierarchy:
>
> 1. I don't like CacheAsync, it is ugly.
>
> 2. If IgniteCache extends AsyncCache then we can't use the same names for
> methods, we will be forced to use *blaAsync(...)* format
> which is ugly for me as well. Also this will pollute sync API with async
> one, while we are trying to avoid that.
>
> Sergi
>
> 2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
>
> > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> >
> > > The problem with this approach is that not all methods are async. E.g.
> > > name(), lock(K), iterator(), etc.. So you should either mix sync and
> > async
> > > methods in AsyncCache still, or expose only async methods.
> >
> >
> > I think AsyncCache, or rather CacheAsync, should expose only async
> methods.
> > Moreover, should IgniteCache simply extend CacheAsync API?
> >
> >
> > > In the latter case we will require backwards
> > > transformation: IgniteCache AsyncCache.sync().
> > >
> >
> > Not sure this is needed.
> >
> >
> > > Consistency between platforms should have minimal priority. .Net and
> Java
> > > are very different. For example we cannot even have "V Get(K)" method
> in
> > > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net
> supports
> > > structs and have full generics support and naive Java approach simply
> > > doesn't work here. Base concepts must be the same across platforms, but
> > > methods signatures and grouping will be different.
> > >
> >
> > I disagree here. I think consistency matters. Moreover, based on the
> > previous .NET examples you have provided, I do not see much difference
> > between .NET and Java, other than different syntax. I think the same
> > CacheAsync design can be applied to both.
> >
> >
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> > sergi.vladykin@gmail.com>
> > > wrote:
> > >
> > > > In my view we should not pollute sync APIs with all async methods,
> > > > definitely we have to separate them
> > > > for better UX.
> > > >
> > > > Currently on Java we have IgniteAsyncSupport with method withAsync()
> > > which
> > > > returns the same sync API
> > > > but that API works in broken manner. Instead it should look like the
> > > > following IMO
> > > >
> > > > interface AsyncSupport<X> {
> > > >     X async();
> > > > }
> > > >
> > > > Where X will be an interface with respective async API.  For example
> > for
> > > > IngneCache we will have AsyncCache
> > > > with all the respective async variants of all methods. Like this
> > > >
> > > > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> > > >     V get(K key);
> > > > }
> > > >
> > > >
> > > > interface AsyncCache<K,V> {
> > > >     IgniteFuture<V> get(K key);
> > > > }
> > > >
> > > > From implementation standpoint both interfaces can be implemented by
> > the
> > > > same class but for user API
> > > > they will be conveniently separated. Implementation of every sync
> > method
> > > is
> > > > trivial if we have
> > > > async counterpart: just call get() on received future.
> > > >
> > > > From documentation point of view we just have to write on each method
> > > that
> > > > it is a async variant of some
> > > > method on main API like following:
> > > >
> > > >    /**
> > > >      * Asynchronous variant of method {@link
> IgniteCache#get(Object)}.
> > > >      */
> > > >
> > > > This way we will not need to maintain the same docs for all sync and
> > > async
> > > > methods.
> > > >
> > > > Sorry, I'm not an expert in .Net but I believe this approach will fit
> > > .Net
> > > > as well, so it can be consistent across platforms.
> > > >
> > > > Sergi
> > > >
> > > >
> > > >
> > > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <dsetrakyan@apache.org
> >:
> > > >
> > > > > Do I understand correctly that you are suggesting adding
> "Async(..)"
> > > > > counterparts for all the synchronous methods?
> > > > >
> > > > > Are there any objections about this? If we do it in .NET, then we
> > might
> > > > as
> > > > > well do it in Java, because in my view the same reasoning can be
> made
> > > for
> > > > > Java. This will cause significant proliferation of Async methods.
> For
> > > > > example just on IgniteCache API, we will have to add about 40
> Async()
> > > > > methods.
> > > > >
> > > > > D.
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> > vozerov@gridgain.com
> > > >
> > > > > wrote:
> > > > >
> > > > > > No. "await" is actually return from the method immediately. Let
> me
> > > show
> > > > > it
> > > > > > again:
> > > > > >
> > > > > > async Task<int> GetAndMultiply() {
> > > > > >     Task<int> res =  cache.GetAsync(1);
> > > > > >
> > > > > >     await res;
> > > > > >
> > > > > >     return res.Result * res.Result;
> > > > > > }
> > > > > >
> > > > > > maps to the following pseudo-code in Java:
> > > > > >
> > > > > > Future<Integer> getAndMultiply() {
> > > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > > >
> > > > > >     return res.chain((f) => {
> > > > > >         return f.get() * f.get();
> > > > > >     });
> > > > > > }
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> > yzhdanov@apache.org>
> > > > > > wrote:
> > > > > >
> > > > > > > Is current thread blocked until "await" instruction is
> completed
> > in
> > > > > > > parallel thread?
> > > > > > >
> > > > > > > --Yakov
> > > > > > >
> > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> vozerov@gridgain.com
> > >:
> > > > > > >
> > > > > > > > Example with Get() operation:
> > > > > > > >
> > > > > > > > async Task<int> GetAndMultiply() {
> > > > > > > >     // This line is executed in current thread.
> > > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > > >
> > > > > > > >     await res;
> > > > > > > >
> > > > > > > >     // This code is executed in another thread when res is
> > ready.
> > > > > > > >     int mul = res.Result * res.Result;
> > > > > > > >
> > > > > > > >     return mul;
> > > > > > > > }
> > > > > > > >
> > > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > > dsetrakyan@apache.org
> > > > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > vozerov@gridgain.com
> > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Guys, let's try keeping this topic focused on .Net
> please,
> > > > > because
> > > > > > > the
> > > > > > > > > > product is not released yet and we can create any API we
> > > like.
> > > > > > > > > >
> > > > > > > > > > Dima, answering your question about async/await - this is
> > > > > actually
> > > > > > > > native
> > > > > > > > > > continuation support in .Net. Consider the following .Net
> > > > method:
> > > > > > > > > >
> > > > > > > > > > async void PutAndPrint() {
> > > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > > >
> > > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > And what if the method putAsync would return a value. How
> > would
> > > > > this
> > > > > > > code
> > > > > > > > > change?
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Sergi Vladykin <se...@gmail.com>.
Dmitriy,

I mostly agree with your points except naming and hierarchy:

1. I don't like CacheAsync, it is ugly.

2. If IgniteCache extends AsyncCache then we can't use the same names for
methods, we will be forced to use *blaAsync(...)* format
which is ugly for me as well. Also this will pollute sync API with async
one, while we are trying to avoid that.

Sergi

2015-10-12 20:28 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:

> On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
>
> > The problem with this approach is that not all methods are async. E.g.
> > name(), lock(K), iterator(), etc.. So you should either mix sync and
> async
> > methods in AsyncCache still, or expose only async methods.
>
>
> I think AsyncCache, or rather CacheAsync, should expose only async methods.
> Moreover, should IgniteCache simply extend CacheAsync API?
>
>
> > In the latter case we will require backwards
> > transformation: IgniteCache AsyncCache.sync().
> >
>
> Not sure this is needed.
>
>
> > Consistency between platforms should have minimal priority. .Net and Java
> > are very different. For example we cannot even have "V Get(K)" method in
> > .Net cache. Instead we have "V TryGet(K, out bool)" because .Net supports
> > structs and have full generics support and naive Java approach simply
> > doesn't work here. Base concepts must be the same across platforms, but
> > methods signatures and grouping will be different.
> >
>
> I disagree here. I think consistency matters. Moreover, based on the
> previous .NET examples you have provided, I do not see much difference
> between .NET and Java, other than different syntax. I think the same
> CacheAsync design can be applied to both.
>
>
> >
> >
> >
> > On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <
> sergi.vladykin@gmail.com>
> > wrote:
> >
> > > In my view we should not pollute sync APIs with all async methods,
> > > definitely we have to separate them
> > > for better UX.
> > >
> > > Currently on Java we have IgniteAsyncSupport with method withAsync()
> > which
> > > returns the same sync API
> > > but that API works in broken manner. Instead it should look like the
> > > following IMO
> > >
> > > interface AsyncSupport<X> {
> > >     X async();
> > > }
> > >
> > > Where X will be an interface with respective async API.  For example
> for
> > > IngneCache we will have AsyncCache
> > > with all the respective async variants of all methods. Like this
> > >
> > > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> > >     V get(K key);
> > > }
> > >
> > >
> > > interface AsyncCache<K,V> {
> > >     IgniteFuture<V> get(K key);
> > > }
> > >
> > > From implementation standpoint both interfaces can be implemented by
> the
> > > same class but for user API
> > > they will be conveniently separated. Implementation of every sync
> method
> > is
> > > trivial if we have
> > > async counterpart: just call get() on received future.
> > >
> > > From documentation point of view we just have to write on each method
> > that
> > > it is a async variant of some
> > > method on main API like following:
> > >
> > >    /**
> > >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> > >      */
> > >
> > > This way we will not need to maintain the same docs for all sync and
> > async
> > > methods.
> > >
> > > Sorry, I'm not an expert in .Net but I believe this approach will fit
> > .Net
> > > as well, so it can be consistent across platforms.
> > >
> > > Sergi
> > >
> > >
> > >
> > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> > >
> > > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > > counterparts for all the synchronous methods?
> > > >
> > > > Are there any objections about this? If we do it in .NET, then we
> might
> > > as
> > > > well do it in Java, because in my view the same reasoning can be made
> > for
> > > > Java. This will cause significant proliferation of Async methods. For
> > > > example just on IgniteCache API, we will have to add about 40 Async()
> > > > methods.
> > > >
> > > > D.
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> vozerov@gridgain.com
> > >
> > > > wrote:
> > > >
> > > > > No. "await" is actually return from the method immediately. Let me
> > show
> > > > it
> > > > > again:
> > > > >
> > > > > async Task<int> GetAndMultiply() {
> > > > >     Task<int> res =  cache.GetAsync(1);
> > > > >
> > > > >     await res;
> > > > >
> > > > >     return res.Result * res.Result;
> > > > > }
> > > > >
> > > > > maps to the following pseudo-code in Java:
> > > > >
> > > > > Future<Integer> getAndMultiply() {
> > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > >
> > > > >     return res.chain((f) => {
> > > > >         return f.get() * f.get();
> > > > >     });
> > > > > }
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> yzhdanov@apache.org>
> > > > > wrote:
> > > > >
> > > > > > Is current thread blocked until "await" instruction is completed
> in
> > > > > > parallel thread?
> > > > > >
> > > > > > --Yakov
> > > > > >
> > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vozerov@gridgain.com
> >:
> > > > > >
> > > > > > > Example with Get() operation:
> > > > > > >
> > > > > > > async Task<int> GetAndMultiply() {
> > > > > > >     // This line is executed in current thread.
> > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > >
> > > > > > >     await res;
> > > > > > >
> > > > > > >     // This code is executed in another thread when res is
> ready.
> > > > > > >     int mul = res.Result * res.Result;
> > > > > > >
> > > > > > >     return mul;
> > > > > > > }
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > dsetrakyan@apache.org
> > > > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > > because
> > > > > > the
> > > > > > > > > product is not released yet and we can create any API we
> > like.
> > > > > > > > >
> > > > > > > > > Dima, answering your question about async/await - this is
> > > > actually
> > > > > > > native
> > > > > > > > > continuation support in .Net. Consider the following .Net
> > > method:
> > > > > > > > >
> > > > > > > > > async void PutAndPrint() {
> > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > >
> > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > }
> > > > > > > > >
> > > > > > > >
> > > > > > > > And what if the method putAsync would return a value. How
> would
> > > > this
> > > > > > code
> > > > > > > > change?
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <vo...@gridgain.com>
wrote:


> The problem with this approach is that not all methods are async. E.g.
> name(), lock(K), iterator(), etc.. So you should either mix sync and async
> methods in AsyncCache still, or expose only async methods.


I think AsyncCache, or rather CacheAsync, should expose only async methods.
Moreover, should IgniteCache simply extend CacheAsync API?


> In the latter case we will require backwards
> transformation: IgniteCache AsyncCache.sync().
>

Not sure this is needed.


> Consistency between platforms should have minimal priority. .Net and Java
> are very different. For example we cannot even have "V Get(K)" method in
> .Net cache. Instead we have "V TryGet(K, out bool)" because .Net supports
> structs and have full generics support and naive Java approach simply
> doesn't work here. Base concepts must be the same across platforms, but
> methods signatures and grouping will be different.
>

I disagree here. I think consistency matters. Moreover, based on the
previous .NET examples you have provided, I do not see much difference
between .NET and Java, other than different syntax. I think the same
CacheAsync design can be applied to both.


>
>
>
> On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > In my view we should not pollute sync APIs with all async methods,
> > definitely we have to separate them
> > for better UX.
> >
> > Currently on Java we have IgniteAsyncSupport with method withAsync()
> which
> > returns the same sync API
> > but that API works in broken manner. Instead it should look like the
> > following IMO
> >
> > interface AsyncSupport<X> {
> >     X async();
> > }
> >
> > Where X will be an interface with respective async API.  For example for
> > IngneCache we will have AsyncCache
> > with all the respective async variants of all methods. Like this
> >
> > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> >     V get(K key);
> > }
> >
> >
> > interface AsyncCache<K,V> {
> >     IgniteFuture<V> get(K key);
> > }
> >
> > From implementation standpoint both interfaces can be implemented by the
> > same class but for user API
> > they will be conveniently separated. Implementation of every sync method
> is
> > trivial if we have
> > async counterpart: just call get() on received future.
> >
> > From documentation point of view we just have to write on each method
> that
> > it is a async variant of some
> > method on main API like following:
> >
> >    /**
> >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> >      */
> >
> > This way we will not need to maintain the same docs for all sync and
> async
> > methods.
> >
> > Sorry, I'm not an expert in .Net but I believe this approach will fit
> .Net
> > as well, so it can be consistent across platforms.
> >
> > Sergi
> >
> >
> >
> > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > counterparts for all the synchronous methods?
> > >
> > > Are there any objections about this? If we do it in .NET, then we might
> > as
> > > well do it in Java, because in my view the same reasoning can be made
> for
> > > Java. This will cause significant proliferation of Async methods. For
> > > example just on IgniteCache API, we will have to add about 40 Async()
> > > methods.
> > >
> > > D.
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vozerov@gridgain.com
> >
> > > wrote:
> > >
> > > > No. "await" is actually return from the method immediately. Let me
> show
> > > it
> > > > again:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     Task<int> res =  cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     return res.Result * res.Result;
> > > > }
> > > >
> > > > maps to the following pseudo-code in Java:
> > > >
> > > > Future<Integer> getAndMultiply() {
> > > >     Future<Integer> res =  cache.getAsync(1);
> > > >
> > > >     return res.chain((f) => {
> > > >         return f.get() * f.get();
> > > >     });
> > > > }
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > > >
> > > > > > Example with Get() operation:
> > > > > >
> > > > > > async Task<int> GetAndMultiply() {
> > > > > >     // This line is executed in current thread.
> > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > >
> > > > > >     await res;
> > > > > >
> > > > > >     // This code is executed in another thread when res is ready.
> > > > > >     int mul = res.Result * res.Result;
> > > > > >
> > > > > >     return mul;
> > > > > > }
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > dsetrakyan@apache.org
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > because
> > > > > the
> > > > > > > > product is not released yet and we can create any API we
> like.
> > > > > > > >
> > > > > > > > Dima, answering your question about async/await - this is
> > > actually
> > > > > > native
> > > > > > > > continuation support in .Net. Consider the following .Net
> > method:
> > > > > > > >
> > > > > > > > async void PutAndPrint() {
> > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > >
> > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > }
> > > > > > > >
> > > > > > >
> > > > > > > And what if the method putAsync would return a value. How would
> > > this
> > > > > code
> > > > > > > change?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Sergi Vladykin <se...@gmail.com>.
Vladimir,

I don't see why it is an issue that not all Cache methods will have async
variants,
AsyncCache just will have only needed async methods.

Also I don't see why we need backward transformation from async to sync,
as a user you should always pass IgniteCache everywhere and
use async as needed like *cache.async().get("myKey")*.

I agree that IgniteCache.get() != AsyncCache.get().get(), I was a bit too
optimistic
about it, but it is not a show stopper as well, just a bit more efforts
will be needed.
Anyways these sync and async implementations will follow the same patterns
all the time.

As for platforms consistency I'm for it where it makes sense, but I believe
you know better :)

Sergi

2015-10-12 20:15 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:

> Sergi,
>
> Pavel and I thought about this. The problem with this approach is that not
> all methods are async. E.g. name(), lock(K), iterator(), etc.. So you
> should either mix sync and async methods in AsyncCache still, or expose
> only async methods. In the latter case we will require backwards
> transformation: IgniteCache AsyncCache.sync().
>
> Looks like there is no ideal solutions. We should just pick one.
>
> Also please note that IgniteCache.get() != AsyncCache.get().get(). Sync and
> async operations do not go through the same path in general case. Otherwise
> sync operations could be blocked by async operations due to exhausted
> semaphore. We found a deadlock in IGFS because of this several days ago.
>
> Consistency between platforms should have minimal priority. .Net and Java
> are very different. For example we cannot even have "V Get(K)" method in
> .Net cache. Instead we have "V TryGet(K, out bool)" because .Net supports
> structs and have full generics support and naive Java approach simply
> doesn't work here. Base concepts must be the same across platforms, but
> methods signatures and grouping will be different.
>
>
>
>
> On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > In my view we should not pollute sync APIs with all async methods,
> > definitely we have to separate them
> > for better UX.
> >
> > Currently on Java we have IgniteAsyncSupport with method withAsync()
> which
> > returns the same sync API
> > but that API works in broken manner. Instead it should look like the
> > following IMO
> >
> > interface AsyncSupport<X> {
> >     X async();
> > }
> >
> > Where X will be an interface with respective async API.  For example for
> > IngneCache we will have AsyncCache
> > with all the respective async variants of all methods. Like this
> >
> > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> >     V get(K key);
> > }
> >
> >
> > interface AsyncCache<K,V> {
> >     IgniteFuture<V> get(K key);
> > }
> >
> > From implementation standpoint both interfaces can be implemented by the
> > same class but for user API
> > they will be conveniently separated. Implementation of every sync method
> is
> > trivial if we have
> > async counterpart: just call get() on received future.
> >
> > From documentation point of view we just have to write on each method
> that
> > it is a async variant of some
> > method on main API like following:
> >
> >    /**
> >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> >      */
> >
> > This way we will not need to maintain the same docs for all sync and
> async
> > methods.
> >
> > Sorry, I'm not an expert in .Net but I believe this approach will fit
> .Net
> > as well, so it can be consistent across platforms.
> >
> > Sergi
> >
> >
> >
> > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > counterparts for all the synchronous methods?
> > >
> > > Are there any objections about this? If we do it in .NET, then we might
> > as
> > > well do it in Java, because in my view the same reasoning can be made
> for
> > > Java. This will cause significant proliferation of Async methods. For
> > > example just on IgniteCache API, we will have to add about 40 Async()
> > > methods.
> > >
> > > D.
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vozerov@gridgain.com
> >
> > > wrote:
> > >
> > > > No. "await" is actually return from the method immediately. Let me
> show
> > > it
> > > > again:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     Task<int> res =  cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     return res.Result * res.Result;
> > > > }
> > > >
> > > > maps to the following pseudo-code in Java:
> > > >
> > > > Future<Integer> getAndMultiply() {
> > > >     Future<Integer> res =  cache.getAsync(1);
> > > >
> > > >     return res.chain((f) => {
> > > >         return f.get() * f.get();
> > > >     });
> > > > }
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > > >
> > > > > > Example with Get() operation:
> > > > > >
> > > > > > async Task<int> GetAndMultiply() {
> > > > > >     // This line is executed in current thread.
> > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > >
> > > > > >     await res;
> > > > > >
> > > > > >     // This code is executed in another thread when res is ready.
> > > > > >     int mul = res.Result * res.Result;
> > > > > >
> > > > > >     return mul;
> > > > > > }
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > dsetrakyan@apache.org
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > because
> > > > > the
> > > > > > > > product is not released yet and we can create any API we
> like.
> > > > > > > >
> > > > > > > > Dima, answering your question about async/await - this is
> > > actually
> > > > > > native
> > > > > > > > continuation support in .Net. Consider the following .Net
> > method:
> > > > > > > >
> > > > > > > > async void PutAndPrint() {
> > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > >
> > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > }
> > > > > > > >
> > > > > > >
> > > > > > > And what if the method putAsync would return a value. How would
> > > this
> > > > > code
> > > > > > > change?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Sergi,

Pavel and I thought about this. The problem with this approach is that not
all methods are async. E.g. name(), lock(K), iterator(), etc.. So you
should either mix sync and async methods in AsyncCache still, or expose
only async methods. In the latter case we will require backwards
transformation: IgniteCache AsyncCache.sync().

Looks like there is no ideal solutions. We should just pick one.

Also please note that IgniteCache.get() != AsyncCache.get().get(). Sync and
async operations do not go through the same path in general case. Otherwise
sync operations could be blocked by async operations due to exhausted
semaphore. We found a deadlock in IGFS because of this several days ago.

Consistency between platforms should have minimal priority. .Net and Java
are very different. For example we cannot even have "V Get(K)" method in
.Net cache. Instead we have "V TryGet(K, out bool)" because .Net supports
structs and have full generics support and naive Java approach simply
doesn't work here. Base concepts must be the same across platforms, but
methods signatures and grouping will be different.




On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <se...@gmail.com>
wrote:

> In my view we should not pollute sync APIs with all async methods,
> definitely we have to separate them
> for better UX.
>
> Currently on Java we have IgniteAsyncSupport with method withAsync() which
> returns the same sync API
> but that API works in broken manner. Instead it should look like the
> following IMO
>
> interface AsyncSupport<X> {
>     X async();
> }
>
> Where X will be an interface with respective async API.  For example for
> IngneCache we will have AsyncCache
> with all the respective async variants of all methods. Like this
>
> interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
>     V get(K key);
> }
>
>
> interface AsyncCache<K,V> {
>     IgniteFuture<V> get(K key);
> }
>
> From implementation standpoint both interfaces can be implemented by the
> same class but for user API
> they will be conveniently separated. Implementation of every sync method is
> trivial if we have
> async counterpart: just call get() on received future.
>
> From documentation point of view we just have to write on each method that
> it is a async variant of some
> method on main API like following:
>
>    /**
>      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
>      */
>
> This way we will not need to maintain the same docs for all sync and async
> methods.
>
> Sorry, I'm not an expert in .Net but I believe this approach will fit .Net
> as well, so it can be consistent across platforms.
>
> Sergi
>
>
>
> 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
>
> > Do I understand correctly that you are suggesting adding "Async(..)"
> > counterparts for all the synchronous methods?
> >
> > Are there any objections about this? If we do it in .NET, then we might
> as
> > well do it in Java, because in my view the same reasoning can be made for
> > Java. This will cause significant proliferation of Async methods. For
> > example just on IgniteCache API, we will have to add about 40 Async()
> > methods.
> >
> > D.
> >
> >
> >
> > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > No. "await" is actually return from the method immediately. Let me show
> > it
> > > again:
> > >
> > > async Task<int> GetAndMultiply() {
> > >     Task<int> res =  cache.GetAsync(1);
> > >
> > >     await res;
> > >
> > >     return res.Result * res.Result;
> > > }
> > >
> > > maps to the following pseudo-code in Java:
> > >
> > > Future<Integer> getAndMultiply() {
> > >     Future<Integer> res =  cache.getAsync(1);
> > >
> > >     return res.chain((f) => {
> > >         return f.get() * f.get();
> > >     });
> > > }
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > wrote:
> > >
> > > > Is current thread blocked until "await" instruction is completed in
> > > > parallel thread?
> > > >
> > > > --Yakov
> > > >
> > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > >
> > > > > Example with Get() operation:
> > > > >
> > > > > async Task<int> GetAndMultiply() {
> > > > >     // This line is executed in current thread.
> > > > >     Task<int> res = cache.GetAsync(1);
> > > > >
> > > > >     await res;
> > > > >
> > > > >     // This code is executed in another thread when res is ready.
> > > > >     int mul = res.Result * res.Result;
> > > > >
> > > > >     return mul;
> > > > > }
> > > > >
> > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > dsetrakyan@apache.org
> > > > > >
> > > > > wrote:
> > > > >
> > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com
> > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > because
> > > > the
> > > > > > > product is not released yet and we can create any API we like.
> > > > > > >
> > > > > > > Dima, answering your question about async/await - this is
> > actually
> > > > > native
> > > > > > > continuation support in .Net. Consider the following .Net
> method:
> > > > > > >
> > > > > > > async void PutAndPrint() {
> > > > > > >     await cache.PutAsync(1, 1);
> > > > > > >
> > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > }
> > > > > > >
> > > > > >
> > > > > > And what if the method putAsync would return a value. How would
> > this
> > > > code
> > > > > > change?
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Nikita Ivanov <ni...@gmail.com>.
+1 on Sergey's idea too.

--
Nikita Ivanov


On Mon, Oct 12, 2015 at 10:10 AM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> I think I like Sergey's idea. Any way to make it backward compatible?
>
> On Mon, Oct 12, 2015 at 9:53 AM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > In my view we should not pollute sync APIs with all async methods,
> > definitely we have to separate them
> > for better UX.
> >
> > Currently on Java we have IgniteAsyncSupport with method withAsync()
> which
> > returns the same sync API
> > but that API works in broken manner. Instead it should look like the
> > following IMO
> >
> > interface AsyncSupport<X> {
> >     X async();
> > }
> >
> > Where X will be an interface with respective async API.  For example for
> > IngneCache we will have AsyncCache
> > with all the respective async variants of all methods. Like this
> >
> > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> >     V get(K key);
> > }
> >
> >
> > interface AsyncCache<K,V> {
> >     IgniteFuture<V> get(K key);
> > }
> >
> > From implementation standpoint both interfaces can be implemented by the
> > same class but for user API
> > they will be conveniently separated. Implementation of every sync method
> is
> > trivial if we have
> > async counterpart: just call get() on received future.
> >
> > From documentation point of view we just have to write on each method
> that
> > it is a async variant of some
> > method on main API like following:
> >
> >    /**
> >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> >      */
> >
> > This way we will not need to maintain the same docs for all sync and
> async
> > methods.
> >
> > Sorry, I'm not an expert in .Net but I believe this approach will fit
> .Net
> > as well, so it can be consistent across platforms.
> >
> > Sergi
> >
> >
> >
> > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > counterparts for all the synchronous methods?
> > >
> > > Are there any objections about this? If we do it in .NET, then we might
> > as
> > > well do it in Java, because in my view the same reasoning can be made
> for
> > > Java. This will cause significant proliferation of Async methods. For
> > > example just on IgniteCache API, we will have to add about 40 Async()
> > > methods.
> > >
> > > D.
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vozerov@gridgain.com
> >
> > > wrote:
> > >
> > > > No. "await" is actually return from the method immediately. Let me
> show
> > > it
> > > > again:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     Task<int> res =  cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     return res.Result * res.Result;
> > > > }
> > > >
> > > > maps to the following pseudo-code in Java:
> > > >
> > > > Future<Integer> getAndMultiply() {
> > > >     Future<Integer> res =  cache.getAsync(1);
> > > >
> > > >     return res.chain((f) => {
> > > >         return f.get() * f.get();
> > > >     });
> > > > }
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > > >
> > > > > > Example with Get() operation:
> > > > > >
> > > > > > async Task<int> GetAndMultiply() {
> > > > > >     // This line is executed in current thread.
> > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > >
> > > > > >     await res;
> > > > > >
> > > > > >     // This code is executed in another thread when res is ready.
> > > > > >     int mul = res.Result * res.Result;
> > > > > >
> > > > > >     return mul;
> > > > > > }
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > dsetrakyan@apache.org
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > because
> > > > > the
> > > > > > > > product is not released yet and we can create any API we
> like.
> > > > > > > >
> > > > > > > > Dima, answering your question about async/await - this is
> > > actually
> > > > > > native
> > > > > > > > continuation support in .Net. Consider the following .Net
> > method:
> > > > > > > >
> > > > > > > > async void PutAndPrint() {
> > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > >
> > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > }
> > > > > > > >
> > > > > > >
> > > > > > > And what if the method putAsync would return a value. How would
> > > this
> > > > > code
> > > > > > > change?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
I think I like Sergey's idea. Any way to make it backward compatible?

On Mon, Oct 12, 2015 at 9:53 AM, Sergi Vladykin <se...@gmail.com>
wrote:

> In my view we should not pollute sync APIs with all async methods,
> definitely we have to separate them
> for better UX.
>
> Currently on Java we have IgniteAsyncSupport with method withAsync() which
> returns the same sync API
> but that API works in broken manner. Instead it should look like the
> following IMO
>
> interface AsyncSupport<X> {
>     X async();
> }
>
> Where X will be an interface with respective async API.  For example for
> IngneCache we will have AsyncCache
> with all the respective async variants of all methods. Like this
>
> interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
>     V get(K key);
> }
>
>
> interface AsyncCache<K,V> {
>     IgniteFuture<V> get(K key);
> }
>
> From implementation standpoint both interfaces can be implemented by the
> same class but for user API
> they will be conveniently separated. Implementation of every sync method is
> trivial if we have
> async counterpart: just call get() on received future.
>
> From documentation point of view we just have to write on each method that
> it is a async variant of some
> method on main API like following:
>
>    /**
>      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
>      */
>
> This way we will not need to maintain the same docs for all sync and async
> methods.
>
> Sorry, I'm not an expert in .Net but I believe this approach will fit .Net
> as well, so it can be consistent across platforms.
>
> Sergi
>
>
>
> 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
>
> > Do I understand correctly that you are suggesting adding "Async(..)"
> > counterparts for all the synchronous methods?
> >
> > Are there any objections about this? If we do it in .NET, then we might
> as
> > well do it in Java, because in my view the same reasoning can be made for
> > Java. This will cause significant proliferation of Async methods. For
> > example just on IgniteCache API, we will have to add about 40 Async()
> > methods.
> >
> > D.
> >
> >
> >
> > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > No. "await" is actually return from the method immediately. Let me show
> > it
> > > again:
> > >
> > > async Task<int> GetAndMultiply() {
> > >     Task<int> res =  cache.GetAsync(1);
> > >
> > >     await res;
> > >
> > >     return res.Result * res.Result;
> > > }
> > >
> > > maps to the following pseudo-code in Java:
> > >
> > > Future<Integer> getAndMultiply() {
> > >     Future<Integer> res =  cache.getAsync(1);
> > >
> > >     return res.chain((f) => {
> > >         return f.get() * f.get();
> > >     });
> > > }
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > wrote:
> > >
> > > > Is current thread blocked until "await" instruction is completed in
> > > > parallel thread?
> > > >
> > > > --Yakov
> > > >
> > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > >
> > > > > Example with Get() operation:
> > > > >
> > > > > async Task<int> GetAndMultiply() {
> > > > >     // This line is executed in current thread.
> > > > >     Task<int> res = cache.GetAsync(1);
> > > > >
> > > > >     await res;
> > > > >
> > > > >     // This code is executed in another thread when res is ready.
> > > > >     int mul = res.Result * res.Result;
> > > > >
> > > > >     return mul;
> > > > > }
> > > > >
> > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > dsetrakyan@apache.org
> > > > > >
> > > > > wrote:
> > > > >
> > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com
> > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > because
> > > > the
> > > > > > > product is not released yet and we can create any API we like.
> > > > > > >
> > > > > > > Dima, answering your question about async/await - this is
> > actually
> > > > > native
> > > > > > > continuation support in .Net. Consider the following .Net
> method:
> > > > > > >
> > > > > > > async void PutAndPrint() {
> > > > > > >     await cache.PutAsync(1, 1);
> > > > > > >
> > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > }
> > > > > > >
> > > > > >
> > > > > > And what if the method putAsync would return a value. How would
> > this
> > > > code
> > > > > > change?
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Sergi Vladykin <se...@gmail.com>.
Raul,

Yes, my design is an attempt to address exactly the problems you've
mentioned (get rid of state, better type safety, cleaner code).
I'm not an expert in reactive streams, but I believe Future is the most low
level feature possible here, so higher level abstractions
can be build using it.

Sergi


2015-10-13 19:32 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:

> On Tue, Oct 13, 2015 at 9:19 AM, Raul Kripalani <ra...@apache.org> wrote:
>
> > I like this approach.
> >
> > To me, the current API is messy and hacky, and even "spiritually"
> > contradictory, may I say. The whole raison d'être of the current approach
> > seems to be to achieve parity of APIs of IgniteCompute, IgniteMessaging,
> > etc. in sync and async modes. However, truth of the matter is that we
> only
> > end up honouring half of the API in async mode: the method entry point
> and
> > parameters. The method return type is basically ignored, because all
> > methods in async mode return null since the "virtual" return type is now
> a
> > Future that the user must obtain with a separate code. To me, this is a
> > code smell.
> >
> > Moreover, I would argue that keeping a state (even if in a ThreadLocal)
> > also makes certain use cases impossible or buggy, like Nikita
> illustrated,
> > e.g. passing IgniteCache, IgniteCompute, etc down the stack.
> >
> > In fact, keeping a state in async mode and not in sync is problematic
> > because – to the eyes of the user – they're always interacting with the
> > neutral interfaces IgniteCompute, IgniteCache, etc. They have no
> indication
> > of when a state is being kept and when not – only through documentation,
> > common sense and human memory – something that's error-prone.
> >
> > Obviously the verbosity and fluency of user's code is also a factor to
> > consider, but to me it is secondary. The above points are enough to
> > advocate changing the async APIs.
> >
> > Finally, looking to the future, the current approach does make Ignite
> > difficult to integrate with Reactive Streams. So it's great we're
> > discussing it.
> >
> > @Sergey, the approach you propose would entail adding Async interface
> > variants for each functionality. This is a step in the opposite direction
> > of the spirit of the current API, am I correct? Since this is a change in
> > direction, I would like for most of the team to approve or disapprove.
> >
>
> I personally like Sergey's design. I actually don't see it as a step in the
> opposite direction. I think it achieves the same goal, but in a much
> cleaner fashion. Moreover, it seems to be .NET-friendly as well.
>
>
> >
> > Regards,
> >
> > *Raúl Kripalani*
> > PMC & Committer @ Apache Ignite, Apache Camel | Integration, Big Data and
> > Messaging Engineer
> > http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> > http://blog.raulkr.net | twitter: @raulvk
> >
> > On Mon, Oct 12, 2015 at 5:53 PM, Sergi Vladykin <
> sergi.vladykin@gmail.com>
> > wrote:
> >
> > > In my view we should not pollute sync APIs with all async methods,
> > > definitely we have to separate them
> > > for better UX.
> > >
> > > Currently on Java we have IgniteAsyncSupport with method withAsync()
> > which
> > > returns the same sync API
> > > but that API works in broken manner. Instead it should look like the
> > > following IMO
> > >
> > > interface AsyncSupport<X> {
> > >     X async();
> > > }
> > >
> > > Where X will be an interface with respective async API.  For example
> for
> > > IngneCache we will have AsyncCache
> > > with all the respective async variants of all methods. Like this
> > >
> > > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> > >     V get(K key);
> > > }
> > >
> > >
> > > interface AsyncCache<K,V> {
> > >     IgniteFuture<V> get(K key);
> > > }
> > >
> > > From implementation standpoint both interfaces can be implemented by
> the
> > > same class but for user API
> > > they will be conveniently separated. Implementation of every sync
> method
> > is
> > > trivial if we have
> > > async counterpart: just call get() on received future.
> > >
> > > From documentation point of view we just have to write on each method
> > that
> > > it is a async variant of some
> > > method on main API like following:
> > >
> > >    /**
> > >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> > >      */
> > >
> > > This way we will not need to maintain the same docs for all sync and
> > async
> > > methods.
> > >
> > > Sorry, I'm not an expert in .Net but I believe this approach will fit
> > .Net
> > > as well, so it can be consistent across platforms.
> > >
> > > Sergi
> > >
> > >
> > >
> > > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> > >
> > > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > > counterparts for all the synchronous methods?
> > > >
> > > > Are there any objections about this? If we do it in .NET, then we
> might
> > > as
> > > > well do it in Java, because in my view the same reasoning can be made
> > for
> > > > Java. This will cause significant proliferation of Async methods. For
> > > > example just on IgniteCache API, we will have to add about 40 Async()
> > > > methods.
> > > >
> > > > D.
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <
> vozerov@gridgain.com
> > >
> > > > wrote:
> > > >
> > > > > No. "await" is actually return from the method immediately. Let me
> > show
> > > > it
> > > > > again:
> > > > >
> > > > > async Task<int> GetAndMultiply() {
> > > > >     Task<int> res =  cache.GetAsync(1);
> > > > >
> > > > >     await res;
> > > > >
> > > > >     return res.Result * res.Result;
> > > > > }
> > > > >
> > > > > maps to the following pseudo-code in Java:
> > > > >
> > > > > Future<Integer> getAndMultiply() {
> > > > >     Future<Integer> res =  cache.getAsync(1);
> > > > >
> > > > >     return res.chain((f) => {
> > > > >         return f.get() * f.get();
> > > > >     });
> > > > > }
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <
> yzhdanov@apache.org>
> > > > > wrote:
> > > > >
> > > > > > Is current thread blocked until "await" instruction is completed
> in
> > > > > > parallel thread?
> > > > > >
> > > > > > --Yakov
> > > > > >
> > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vozerov@gridgain.com
> >:
> > > > > >
> > > > > > > Example with Get() operation:
> > > > > > >
> > > > > > > async Task<int> GetAndMultiply() {
> > > > > > >     // This line is executed in current thread.
> > > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > > >
> > > > > > >     await res;
> > > > > > >
> > > > > > >     // This code is executed in another thread when res is
> ready.
> > > > > > >     int mul = res.Result * res.Result;
> > > > > > >
> > > > > > >     return mul;
> > > > > > > }
> > > > > > >
> > > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > > dsetrakyan@apache.org
> > > > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > vozerov@gridgain.com
> > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > > because
> > > > > > the
> > > > > > > > > product is not released yet and we can create any API we
> > like.
> > > > > > > > >
> > > > > > > > > Dima, answering your question about async/await - this is
> > > > actually
> > > > > > > native
> > > > > > > > > continuation support in .Net. Consider the following .Net
> > > method:
> > > > > > > > >
> > > > > > > > > async void PutAndPrint() {
> > > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > > >
> > > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > > }
> > > > > > > > >
> > > > > > > >
> > > > > > > > And what if the method putAsync would return a value. How
> would
> > > > this
> > > > > > code
> > > > > > > > change?
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
On Tue, Oct 13, 2015 at 9:19 AM, Raul Kripalani <ra...@apache.org> wrote:

> I like this approach.
>
> To me, the current API is messy and hacky, and even "spiritually"
> contradictory, may I say. The whole raison d'être of the current approach
> seems to be to achieve parity of APIs of IgniteCompute, IgniteMessaging,
> etc. in sync and async modes. However, truth of the matter is that we only
> end up honouring half of the API in async mode: the method entry point and
> parameters. The method return type is basically ignored, because all
> methods in async mode return null since the "virtual" return type is now a
> Future that the user must obtain with a separate code. To me, this is a
> code smell.
>
> Moreover, I would argue that keeping a state (even if in a ThreadLocal)
> also makes certain use cases impossible or buggy, like Nikita illustrated,
> e.g. passing IgniteCache, IgniteCompute, etc down the stack.
>
> In fact, keeping a state in async mode and not in sync is problematic
> because – to the eyes of the user – they're always interacting with the
> neutral interfaces IgniteCompute, IgniteCache, etc. They have no indication
> of when a state is being kept and when not – only through documentation,
> common sense and human memory – something that's error-prone.
>
> Obviously the verbosity and fluency of user's code is also a factor to
> consider, but to me it is secondary. The above points are enough to
> advocate changing the async APIs.
>
> Finally, looking to the future, the current approach does make Ignite
> difficult to integrate with Reactive Streams. So it's great we're
> discussing it.
>
> @Sergey, the approach you propose would entail adding Async interface
> variants for each functionality. This is a step in the opposite direction
> of the spirit of the current API, am I correct? Since this is a change in
> direction, I would like for most of the team to approve or disapprove.
>

I personally like Sergey's design. I actually don't see it as a step in the
opposite direction. I think it achieves the same goal, but in a much
cleaner fashion. Moreover, it seems to be .NET-friendly as well.


>
> Regards,
>
> *Raúl Kripalani*
> PMC & Committer @ Apache Ignite, Apache Camel | Integration, Big Data and
> Messaging Engineer
> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> http://blog.raulkr.net | twitter: @raulvk
>
> On Mon, Oct 12, 2015 at 5:53 PM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > In my view we should not pollute sync APIs with all async methods,
> > definitely we have to separate them
> > for better UX.
> >
> > Currently on Java we have IgniteAsyncSupport with method withAsync()
> which
> > returns the same sync API
> > but that API works in broken manner. Instead it should look like the
> > following IMO
> >
> > interface AsyncSupport<X> {
> >     X async();
> > }
> >
> > Where X will be an interface with respective async API.  For example for
> > IngneCache we will have AsyncCache
> > with all the respective async variants of all methods. Like this
> >
> > interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
> >     V get(K key);
> > }
> >
> >
> > interface AsyncCache<K,V> {
> >     IgniteFuture<V> get(K key);
> > }
> >
> > From implementation standpoint both interfaces can be implemented by the
> > same class but for user API
> > they will be conveniently separated. Implementation of every sync method
> is
> > trivial if we have
> > async counterpart: just call get() on received future.
> >
> > From documentation point of view we just have to write on each method
> that
> > it is a async variant of some
> > method on main API like following:
> >
> >    /**
> >      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
> >      */
> >
> > This way we will not need to maintain the same docs for all sync and
> async
> > methods.
> >
> > Sorry, I'm not an expert in .Net but I believe this approach will fit
> .Net
> > as well, so it can be consistent across platforms.
> >
> > Sergi
> >
> >
> >
> > 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > Do I understand correctly that you are suggesting adding "Async(..)"
> > > counterparts for all the synchronous methods?
> > >
> > > Are there any objections about this? If we do it in .NET, then we might
> > as
> > > well do it in Java, because in my view the same reasoning can be made
> for
> > > Java. This will cause significant proliferation of Async methods. For
> > > example just on IgniteCache API, we will have to add about 40 Async()
> > > methods.
> > >
> > > D.
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vozerov@gridgain.com
> >
> > > wrote:
> > >
> > > > No. "await" is actually return from the method immediately. Let me
> show
> > > it
> > > > again:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     Task<int> res =  cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     return res.Result * res.Result;
> > > > }
> > > >
> > > > maps to the following pseudo-code in Java:
> > > >
> > > > Future<Integer> getAndMultiply() {
> > > >     Future<Integer> res =  cache.getAsync(1);
> > > >
> > > >     return res.chain((f) => {
> > > >         return f.get() * f.get();
> > > >     });
> > > > }
> > > >
> > > >
> > > >
> > > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > > >
> > > > > > Example with Get() operation:
> > > > > >
> > > > > > async Task<int> GetAndMultiply() {
> > > > > >     // This line is executed in current thread.
> > > > > >     Task<int> res = cache.GetAsync(1);
> > > > > >
> > > > > >     await res;
> > > > > >
> > > > > >     // This code is executed in another thread when res is ready.
> > > > > >     int mul = res.Result * res.Result;
> > > > > >
> > > > > >     return mul;
> > > > > > }
> > > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > > dsetrakyan@apache.org
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > vozerov@gridgain.com
> > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > > because
> > > > > the
> > > > > > > > product is not released yet and we can create any API we
> like.
> > > > > > > >
> > > > > > > > Dima, answering your question about async/await - this is
> > > actually
> > > > > > native
> > > > > > > > continuation support in .Net. Consider the following .Net
> > method:
> > > > > > > >
> > > > > > > > async void PutAndPrint() {
> > > > > > > >     await cache.PutAsync(1, 1);
> > > > > > > >
> > > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > > }
> > > > > > > >
> > > > > > >
> > > > > > > And what if the method putAsync would return a value. How would
> > > this
> > > > > code
> > > > > > > change?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Fwd: .Net: separate methods for async operations.

Posted by Raul Kripalani <ra...@apache.org>.
I like this approach.

To me, the current API is messy and hacky, and even "spiritually"
contradictory, may I say. The whole raison d'être of the current approach
seems to be to achieve parity of APIs of IgniteCompute, IgniteMessaging,
etc. in sync and async modes. However, truth of the matter is that we only
end up honouring half of the API in async mode: the method entry point and
parameters. The method return type is basically ignored, because all
methods in async mode return null since the "virtual" return type is now a
Future that the user must obtain with a separate code. To me, this is a
code smell.

Moreover, I would argue that keeping a state (even if in a ThreadLocal)
also makes certain use cases impossible or buggy, like Nikita illustrated,
e.g. passing IgniteCache, IgniteCompute, etc down the stack.

In fact, keeping a state in async mode and not in sync is problematic
because – to the eyes of the user – they're always interacting with the
neutral interfaces IgniteCompute, IgniteCache, etc. They have no indication
of when a state is being kept and when not – only through documentation,
common sense and human memory – something that's error-prone.

Obviously the verbosity and fluency of user's code is also a factor to
consider, but to me it is secondary. The above points are enough to
advocate changing the async APIs.

Finally, looking to the future, the current approach does make Ignite
difficult to integrate with Reactive Streams. So it's great we're
discussing it.

@Sergey, the approach you propose would entail adding Async interface
variants for each functionality. This is a step in the opposite direction
of the spirit of the current API, am I correct? Since this is a change in
direction, I would like for most of the team to approve or disapprove.

Regards,

*Raúl Kripalani*
PMC & Committer @ Apache Ignite, Apache Camel | Integration, Big Data and
Messaging Engineer
http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
http://blog.raulkr.net | twitter: @raulvk

On Mon, Oct 12, 2015 at 5:53 PM, Sergi Vladykin <se...@gmail.com>
wrote:

> In my view we should not pollute sync APIs with all async methods,
> definitely we have to separate them
> for better UX.
>
> Currently on Java we have IgniteAsyncSupport with method withAsync() which
> returns the same sync API
> but that API works in broken manner. Instead it should look like the
> following IMO
>
> interface AsyncSupport<X> {
>     X async();
> }
>
> Where X will be an interface with respective async API.  For example for
> IngneCache we will have AsyncCache
> with all the respective async variants of all methods. Like this
>
> interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
>     V get(K key);
> }
>
>
> interface AsyncCache<K,V> {
>     IgniteFuture<V> get(K key);
> }
>
> From implementation standpoint both interfaces can be implemented by the
> same class but for user API
> they will be conveniently separated. Implementation of every sync method is
> trivial if we have
> async counterpart: just call get() on received future.
>
> From documentation point of view we just have to write on each method that
> it is a async variant of some
> method on main API like following:
>
>    /**
>      * Asynchronous variant of method {@link IgniteCache#get(Object)}.
>      */
>
> This way we will not need to maintain the same docs for all sync and async
> methods.
>
> Sorry, I'm not an expert in .Net but I believe this approach will fit .Net
> as well, so it can be consistent across platforms.
>
> Sergi
>
>
>
> 2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
>
> > Do I understand correctly that you are suggesting adding "Async(..)"
> > counterparts for all the synchronous methods?
> >
> > Are there any objections about this? If we do it in .NET, then we might
> as
> > well do it in Java, because in my view the same reasoning can be made for
> > Java. This will cause significant proliferation of Async methods. For
> > example just on IgniteCache API, we will have to add about 40 Async()
> > methods.
> >
> > D.
> >
> >
> >
> > On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > No. "await" is actually return from the method immediately. Let me show
> > it
> > > again:
> > >
> > > async Task<int> GetAndMultiply() {
> > >     Task<int> res =  cache.GetAsync(1);
> > >
> > >     await res;
> > >
> > >     return res.Result * res.Result;
> > > }
> > >
> > > maps to the following pseudo-code in Java:
> > >
> > > Future<Integer> getAndMultiply() {
> > >     Future<Integer> res =  cache.getAsync(1);
> > >
> > >     return res.chain((f) => {
> > >         return f.get() * f.get();
> > >     });
> > > }
> > >
> > >
> > >
> > > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > > wrote:
> > >
> > > > Is current thread blocked until "await" instruction is completed in
> > > > parallel thread?
> > > >
> > > > --Yakov
> > > >
> > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > > >
> > > > > Example with Get() operation:
> > > > >
> > > > > async Task<int> GetAndMultiply() {
> > > > >     // This line is executed in current thread.
> > > > >     Task<int> res = cache.GetAsync(1);
> > > > >
> > > > >     await res;
> > > > >
> > > > >     // This code is executed in another thread when res is ready.
> > > > >     int mul = res.Result * res.Result;
> > > > >
> > > > >     return mul;
> > > > > }
> > > > >
> > > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > > dsetrakyan@apache.org
> > > > > >
> > > > > wrote:
> > > > >
> > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > vozerov@gridgain.com
> > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > Guys, let's try keeping this topic focused on .Net please,
> > because
> > > > the
> > > > > > > product is not released yet and we can create any API we like.
> > > > > > >
> > > > > > > Dima, answering your question about async/await - this is
> > actually
> > > > > native
> > > > > > > continuation support in .Net. Consider the following .Net
> method:
> > > > > > >
> > > > > > > async void PutAndPrint() {
> > > > > > >     await cache.PutAsync(1, 1);
> > > > > > >
> > > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > > }
> > > > > > >
> > > > > >
> > > > > > And what if the method putAsync would return a value. How would
> > this
> > > > code
> > > > > > change?
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Sergi Vladykin <se...@gmail.com>.
In my view we should not pollute sync APIs with all async methods,
definitely we have to separate them
for better UX.

Currently on Java we have IgniteAsyncSupport with method withAsync() which
returns the same sync API
but that API works in broken manner. Instead it should look like the
following IMO

interface AsyncSupport<X> {
    X async();
}

Where X will be an interface with respective async API.  For example for
IngneCache we will have AsyncCache
with all the respective async variants of all methods. Like this

interface IgniteCache<K,V> extends AsyncSupport<AsyncCache<K,V>> {
    V get(K key);
}


interface AsyncCache<K,V> {
    IgniteFuture<V> get(K key);
}

>From implementation standpoint both interfaces can be implemented by the
same class but for user API
they will be conveniently separated. Implementation of every sync method is
trivial if we have
async counterpart: just call get() on received future.

>From documentation point of view we just have to write on each method that
it is a async variant of some
method on main API like following:

   /**
     * Asynchronous variant of method {@link IgniteCache#get(Object)}.
     */

This way we will not need to maintain the same docs for all sync and async
methods.

Sorry, I'm not an expert in .Net but I believe this approach will fit .Net
as well, so it can be consistent across platforms.

Sergi



2015-10-12 19:10 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:

> Do I understand correctly that you are suggesting adding "Async(..)"
> counterparts for all the synchronous methods?
>
> Are there any objections about this? If we do it in .NET, then we might as
> well do it in Java, because in my view the same reasoning can be made for
> Java. This will cause significant proliferation of Async methods. For
> example just on IgniteCache API, we will have to add about 40 Async()
> methods.
>
> D.
>
>
>
> On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > No. "await" is actually return from the method immediately. Let me show
> it
> > again:
> >
> > async Task<int> GetAndMultiply() {
> >     Task<int> res =  cache.GetAsync(1);
> >
> >     await res;
> >
> >     return res.Result * res.Result;
> > }
> >
> > maps to the following pseudo-code in Java:
> >
> > Future<Integer> getAndMultiply() {
> >     Future<Integer> res =  cache.getAsync(1);
> >
> >     return res.chain((f) => {
> >         return f.get() * f.get();
> >     });
> > }
> >
> >
> >
> > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > wrote:
> >
> > > Is current thread blocked until "await" instruction is completed in
> > > parallel thread?
> > >
> > > --Yakov
> > >
> > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > >
> > > > Example with Get() operation:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     // This line is executed in current thread.
> > > >     Task<int> res = cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     // This code is executed in another thread when res is ready.
> > > >     int mul = res.Result * res.Result;
> > > >
> > > >     return mul;
> > > > }
> > > >
> > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > dsetrakyan@apache.org
> > > > >
> > > > wrote:
> > > >
> > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > vozerov@gridgain.com
> > > >
> > > > > wrote:
> > > > >
> > > > > > Guys, let's try keeping this topic focused on .Net please,
> because
> > > the
> > > > > > product is not released yet and we can create any API we like.
> > > > > >
> > > > > > Dima, answering your question about async/await - this is
> actually
> > > > native
> > > > > > continuation support in .Net. Consider the following .Net method:
> > > > > >
> > > > > > async void PutAndPrint() {
> > > > > >     await cache.PutAsync(1, 1);
> > > > > >
> > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > }
> > > > > >
> > > > >
> > > > > And what if the method putAsync would return a value. How would
> this
> > > code
> > > > > change?
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Well, as I mentioned before, paired "Async()" methods are very natural to
.Net. When Microsoft creates new API it usually contains such sync/async
pairs.

I am not sure we should do the same thing in Java only because we are going
to do this in .Net. There must be other strong reasons.

On Mon, Oct 12, 2015 at 7:10 PM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> Do I understand correctly that you are suggesting adding "Async(..)"
> counterparts for all the synchronous methods?
>
> Are there any objections about this? If we do it in .NET, then we might as
> well do it in Java, because in my view the same reasoning can be made for
> Java. This will cause significant proliferation of Async methods. For
> example just on IgniteCache API, we will have to add about 40 Async()
> methods.
>
> D.
>
>
>
> On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > No. "await" is actually return from the method immediately. Let me show
> it
> > again:
> >
> > async Task<int> GetAndMultiply() {
> >     Task<int> res =  cache.GetAsync(1);
> >
> >     await res;
> >
> >     return res.Result * res.Result;
> > }
> >
> > maps to the following pseudo-code in Java:
> >
> > Future<Integer> getAndMultiply() {
> >     Future<Integer> res =  cache.getAsync(1);
> >
> >     return res.chain((f) => {
> >         return f.get() * f.get();
> >     });
> > }
> >
> >
> >
> > On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> > wrote:
> >
> > > Is current thread blocked until "await" instruction is completed in
> > > parallel thread?
> > >
> > > --Yakov
> > >
> > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> > >
> > > > Example with Get() operation:
> > > >
> > > > async Task<int> GetAndMultiply() {
> > > >     // This line is executed in current thread.
> > > >     Task<int> res = cache.GetAsync(1);
> > > >
> > > >     await res;
> > > >
> > > >     // This code is executed in another thread when res is ready.
> > > >     int mul = res.Result * res.Result;
> > > >
> > > >     return mul;
> > > > }
> > > >
> > > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > > dsetrakyan@apache.org
> > > > >
> > > > wrote:
> > > >
> > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > vozerov@gridgain.com
> > > >
> > > > > wrote:
> > > > >
> > > > > > Guys, let's try keeping this topic focused on .Net please,
> because
> > > the
> > > > > > product is not released yet and we can create any API we like.
> > > > > >
> > > > > > Dima, answering your question about async/await - this is
> actually
> > > > native
> > > > > > continuation support in .Net. Consider the following .Net method:
> > > > > >
> > > > > > async void PutAndPrint() {
> > > > > >     await cache.PutAsync(1, 1);
> > > > > >
> > > > > >     Console.WriteLine("Put value to cache.");
> > > > > > }
> > > > > >
> > > > >
> > > > > And what if the method putAsync would return a value. How would
> this
> > > code
> > > > > change?
> > > > >
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
Do I understand correctly that you are suggesting adding "Async(..)"
counterparts for all the synchronous methods?

Are there any objections about this? If we do it in .NET, then we might as
well do it in Java, because in my view the same reasoning can be made for
Java. This will cause significant proliferation of Async methods. For
example just on IgniteCache API, we will have to add about 40 Async()
methods.

D.



On Mon, Oct 12, 2015 at 3:45 AM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> No. "await" is actually return from the method immediately. Let me show it
> again:
>
> async Task<int> GetAndMultiply() {
>     Task<int> res =  cache.GetAsync(1);
>
>     await res;
>
>     return res.Result * res.Result;
> }
>
> maps to the following pseudo-code in Java:
>
> Future<Integer> getAndMultiply() {
>     Future<Integer> res =  cache.getAsync(1);
>
>     return res.chain((f) => {
>         return f.get() * f.get();
>     });
> }
>
>
>
> On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org>
> wrote:
>
> > Is current thread blocked until "await" instruction is completed in
> > parallel thread?
> >
> > --Yakov
> >
> > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
> >
> > > Example with Get() operation:
> > >
> > > async Task<int> GetAndMultiply() {
> > >     // This line is executed in current thread.
> > >     Task<int> res = cache.GetAsync(1);
> > >
> > >     await res;
> > >
> > >     // This code is executed in another thread when res is ready.
> > >     int mul = res.Result * res.Result;
> > >
> > >     return mul;
> > > }
> > >
> > > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> > dsetrakyan@apache.org
> > > >
> > > wrote:
> > >
> > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> vozerov@gridgain.com
> > >
> > > > wrote:
> > > >
> > > > > Guys, let's try keeping this topic focused on .Net please, because
> > the
> > > > > product is not released yet and we can create any API we like.
> > > > >
> > > > > Dima, answering your question about async/await - this is actually
> > > native
> > > > > continuation support in .Net. Consider the following .Net method:
> > > > >
> > > > > async void PutAndPrint() {
> > > > >     await cache.PutAsync(1, 1);
> > > > >
> > > > >     Console.WriteLine("Put value to cache.");
> > > > > }
> > > > >
> > > >
> > > > And what if the method putAsync would return a value. How would this
> > code
> > > > change?
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
No. "await" is actually return from the method immediately. Let me show it
again:

async Task<int> GetAndMultiply() {
    Task<int> res =  cache.GetAsync(1);

    await res;

    return res.Result * res.Result;
}

maps to the following pseudo-code in Java:

Future<Integer> getAndMultiply() {
    Future<Integer> res =  cache.getAsync(1);

    return res.chain((f) => {
        return f.get() * f.get();
    });
}



On Mon, Oct 12, 2015 at 1:36 PM, Yakov Zhdanov <yz...@apache.org> wrote:

> Is current thread blocked until "await" instruction is completed in
> parallel thread?
>
> --Yakov
>
> 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:
>
> > Example with Get() operation:
> >
> > async Task<int> GetAndMultiply() {
> >     // This line is executed in current thread.
> >     Task<int> res = cache.GetAsync(1);
> >
> >     await res;
> >
> >     // This code is executed in another thread when res is ready.
> >     int mul = res.Result * res.Result;
> >
> >     return mul;
> > }
> >
> > On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >
> > wrote:
> >
> > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <vozerov@gridgain.com
> >
> > > wrote:
> > >
> > > > Guys, let's try keeping this topic focused on .Net please, because
> the
> > > > product is not released yet and we can create any API we like.
> > > >
> > > > Dima, answering your question about async/await - this is actually
> > native
> > > > continuation support in .Net. Consider the following .Net method:
> > > >
> > > > async void PutAndPrint() {
> > > >     await cache.PutAsync(1, 1);
> > > >
> > > >     Console.WriteLine("Put value to cache.");
> > > > }
> > > >
> > >
> > > And what if the method putAsync would return a value. How would this
> code
> > > change?
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Yakov Zhdanov <yz...@apache.org>.
Is current thread blocked until "await" instruction is completed in
parallel thread?

--Yakov

2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <vo...@gridgain.com>:

> Example with Get() operation:
>
> async Task<int> GetAndMultiply() {
>     // This line is executed in current thread.
>     Task<int> res = cache.GetAsync(1);
>
>     await res;
>
>     // This code is executed in another thread when res is ready.
>     int mul = res.Result * res.Result;
>
>     return mul;
> }
>
> On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <dsetrakyan@apache.org
> >
> wrote:
>
> > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > Guys, let's try keeping this topic focused on .Net please, because the
> > > product is not released yet and we can create any API we like.
> > >
> > > Dima, answering your question about async/await - this is actually
> native
> > > continuation support in .Net. Consider the following .Net method:
> > >
> > > async void PutAndPrint() {
> > >     await cache.PutAsync(1, 1);
> > >
> > >     Console.WriteLine("Put value to cache.");
> > > }
> > >
> >
> > And what if the method putAsync would return a value. How would this code
> > change?
> >
>

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Example with Get() operation:

async Task<int> GetAndMultiply() {
    // This line is executed in current thread.
    Task<int> res = cache.GetAsync(1);

    await res;

    // This code is executed in another thread when res is ready.
    int mul = res.Result * res.Result;

    return mul;
}

On Mon, Oct 12, 2015 at 10:12 AM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > Guys, let's try keeping this topic focused on .Net please, because the
> > product is not released yet and we can create any API we like.
> >
> > Dima, answering your question about async/await - this is actually native
> > continuation support in .Net. Consider the following .Net method:
> >
> > async void PutAndPrint() {
> >     await cache.PutAsync(1, 1);
> >
> >     Console.WriteLine("Put value to cache.");
> > }
> >
>
> And what if the method putAsync would return a value. How would this code
> change?
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> Guys, let's try keeping this topic focused on .Net please, because the
> product is not released yet and we can create any API we like.
>
> Dima, answering your question about async/await - this is actually native
> continuation support in .Net. Consider the following .Net method:
>
> async void PutAndPrint() {
>     await cache.PutAsync(1, 1);
>
>     Console.WriteLine("Put value to cache.");
> }
>

And what if the method putAsync would return a value. How would this code
change?

Re: .Net: separate methods for async operations.

Posted by Vladimir Ozerov <vo...@gridgain.com>.
Guys, let's try keeping this topic focused on .Net please, because the
product is not released yet and we can create any API we like.

Dima, answering your question about async/await - this is actually native
continuation support in .Net. Consider the following .Net method:

async void PutAndPrint() {
    await cache.PutAsync(1, 1);

    Console.WriteLine("Put value to cache.");
}

In Java it maps to somewhat like this (not strict, but idea is the same):

IgniteFuture getAndPrint() {
    cache.put(1, 1);

    return cache.future().chain((f) => {
        System.out.println("Put value to cache.");
    });
}

I.e. in .Net you can write asynchronous code as if it was synchronous - no
explicit callbacks or closures.

.Net platform has completely different view of how and when async
operations should be used. They invested quite a few efforts to develop
vertically integrated threading framework for this. It starts on low WinAPI
level and ends up with Task/async/await concepts on user API level. This
framework is not friendly for 3rd-party products like Ignite and can be
normally used only inside Windows environment. But it covers the needs of
the majority of use cases and is widely accepted by .Net community.

We simply cannot ignore these integral .Net concepts when developing API.

On Sun, Oct 11, 2015 at 7:52 AM, Nikita Ivanov <ni...@gmail.com> wrote:

> I was one of few people who reviewed this design originally and didn't see
> much problem with it (it did seem contrived a bit). I now actually agree
> with "below" sentiment that in retrospect it was a very bad decision and
> APIs is frankly unusable IMHO.
>
> The minute you pass instance of cache elsewhere on the call chain - this
> API cannot be used sanely.
>
> Java vs. .NET, ​API parity vs. feature parity are all good discussions to
> have - but at least Java side needs to be fixed.​
> --
> Nikita Ivanov
>
>
> On Sat, Oct 10, 2015 at 2:39 AM, Sergi Vladykin <se...@gmail.com>
> wrote:
>
> > I think IgniteAsyncSupport is a big piece of crap even in java,
> sync/async
> > API separation definitely must be done in another way.
> >
> > Sergi
> >
> > 2015-10-10 0:40 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
> >
> > > Pavel, can you explain how .NET async semantics are different from
> Java?
> > >
> > > On Fri, Oct 9, 2015 at 1:46 PM, Pavel Tupitsyn <ptupitsyn@gridgain.com
> >
> > > wrote:
> > >
> > > > Hi Dmitry,
> > > >
> > > > > First of all, from my experience, the async APIs are used a lot
> less
> > > > than sync
> > > > ones
> > > >
> > > > This may be true, especially if the API is clunky.
> > > > But .NET has async/await functionality which makes async code a lot
> > > cleaner
> > > > and easier.
> > > > Good async/await support is very important, because it does not block
> > > > current thread, which in turn is important for high load
> applications.
> > > > All modern .NET APIs are async.
> > > >
> > > >
> > > > > Secondly, the scope of this change would be huge.
> > > >
> > > > I don't think so. There are around 40 methods with async support in
> > > current
> > > > Ignite.NET.
> > > > Adding their async counterparts will take a couple of hours at most.
> > > > And it will simplify interop code somewhat because GetFuture goes
> away.
> > > >
> > > >
> > > > > And lastly, I am against having .NET APIs different from Java APIs.
> > > >
> > > > Functionally they will be the same. But we should not try to bring
> Java
> > > > semantics to .NET.
> > > > Async methods in .NET are "T DoSomething()" + "Task<T>
> > > DoSomethingAsync()"
> > > > and we should follow this pattern so our API looks familiar to .NET
> > > > community.
> > > >
> > > >
> > > > > // Line #2
> > > > > cache.Future().Get();
> > > >
> > > > It is cache.GetFuture<X>(). Pay attention to "X". This is very
> > important:
> > > > user has to specify correct return type according to return type of
> > > > operation on "Line 1".
> > > > Very annoying and error prone. There is even a style-checker warning
> > > about
> > > > such things.
> > > >
> > > >
> > > > > 2 lines of code instead of one is not a big deal in my view.
> > > >
> > > > It is 2 times too much, sometimes even more. Imagine a situation
> where
> > > you
> > > > need to perform multiple async operations:
> > > >
> > > > cache.Get(1);
> > > > var res = await cache.GetFuture<int>().ToTask();
> > > >
> > > > compute.Call(new MyCallable(res))
> > > > var res2 = await compute.GetFuture<string>().ToTask()
> > > >
> > > >
> > > > And with proper async API it can even be a one-liner.
> > > > var res2 = await compute.CallAsync(new MyCallable(await
> > > > cache.GetAsync(1)));
> > > >
> > > >
> > > > API is the first thing a programmer sees in the new product. Let's do
> > it
> > > > right.
> > > >
> > > > Thanks,
> > > >
> > > > On Fri, Oct 9, 2015 at 7:17 PM, Dmitriy Setrakyan <
> > dsetrakyan@apache.org
> > > >
> > > > wrote:
> > > >
> > > > > I don't think I like the proposed change.
> > > > >
> > > > > First of all, from my experience, the async APIs are used a lot
> less
> > > than
> > > > > sync ones, so having 2 lines of code for async calls is not a big
> > deal
> > > in
> > > > > my view.
> > > > >
> > > > > Secondly, the scope of this change would be huge. We would have to
> > > double
> > > > > our Compute, Cache, Services, and many other APIs. Seems to me
> like a
> > > > huge
> > > > > amount of effort for a very questionable benefit, if any at all.
> One
> > > can
> > > > > argue, for example, that so many duplicate sync/async methods on
> all
> > > the
> > > > > APIs is more confusing, not less.
> > > > >
> > > > > And lastly, I am against having .NET APIs different from Java APIs.
> > We
> > > > > should have API parity as much as possible between all the
> platforms,
> > > and
> > > > > especially the .NET one, where we provide so many features.
> > > > >
> > > > > On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <
> > ptupitsyn@gridgain.com
> > > >
> > > > > wrote:
> > > > >
> > > > > > As a .Net dev, I support this change very much.
> > > > > >
> > > > > > Current design with 2 method calls is not easy to use, is error
> > > prone,
> > > > > and
> > > > > > is not familiar to .Net crowd:
> > > > > >
> > > > > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > > > > var value = cache.Get(1);   // Is it sync or async? Can't tell
> from
> > > > code.
> > > > >
> > > > > In async mode this always returns 0.
> > > > > >
> > > > >
> > > > > Yes, you are right. But then again, async documentation clearly
> says
> > > that
> > > > > you should get a future to get the actual asynchronous result.
> > > > >
> > > > > The proper code here is:
> > > > > -----------
> > > > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > > >
> > > > > // Line #1
> > > > > cache.Get(1);
> > > > >
> > > > > // Line #2
> > > > > cache.Future().Get();
> > > > > -----------
> > > > >
> > > > > 2 lines of code instead of one is not a big deal in my view.
> > > > >
> > > > >
> > > > > > var future = cache.GetFuture<int>();   // User has to specify
> right
> > > > > generic
> > > > > > argument here. Not convenient, error prone, violates design
> > > guidelines
> > > > > > var actualValue = await future.ToTask();
> > > > > >
> > > > > >
> > > > > > As opposed to:
> > > > > > var value = await cache.GetAsync(1).ToTask();
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > Which is one line, obviously async, with proper generic
> inference.
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <
> > > vozerov@gridgain.com>
> > > > > > wrote:
> > > > > >
> > > > > > > Igniters,
> > > > > > >
> > > > > > > Some time ago we decided to merge sync and async methods. E.g.
> > > > instead
> > > > > of
> > > > > > > ...
> > > > > > >
> > > > > > > interface Cache<K, V> {
> > > > > > >     V get(K key);
> > > > > > >     Future<V> getAsync(K key);
> > > > > > > }
> > > > > > >
> > > > > > > ... we now have:
> > > > > > >
> > > > > > > interface Cache<K, V> extends AsyncSupport {
> > > > > > >     V get(K key);
> > > > > > >     Cache withAsync();
> > > > > > >
> > > > > > >     Future lastFuture(); // From AsyncSupport, returns future
> for
> > > the
> > > > > > last
> > > > > > > operation.
> > > > > > > }
> > > > > > >
> > > > > > > This approach is questionable. Less methods is good, and all
> > > methods
> > > > go
> > > > > > > through JCache API. But async mode became more complex and less
> > > > usable.
> > > > > > > This is especially obvious in Java 8 with its lambdas and
> > > > > > > CompletableFuture.
> > > > > > >
> > > > > > > In .Net we blindly applied this approach as well. But in this
> > world
> > > > > > > AsyncSupport gives even less advantages than in Java:
> > > > > > > 1) There is no JCache spec here;
> > > > > > > 2) Core .Net API very often use paired sync and async
> operations
> > in
> > > > the
> > > > > > > same class near each other - DoMethod(), DoMethodAsync() - and
> > this
> > > > is
> > > > > > what
> > > > > > > users normally expect from async-enabled classes.
> > > > > > > 3) [AsyncSupported] attribute is not highlighted in Visual
> > Studio.
> > > > The
> > > > > > only
> > > > > > > way to understand that method supports async mode is to install
> > > > > ReSharper
> > > > > > > or to look into source code.
> > > > > > > 4) .Net has native continuations support with async/await
> > keywords.
> > > > Our
> > > > > > API
> > > > > > > doesn't support it well.
> > > > > > >
> > > > > > > Having said that I want to return paired "async" operations to
> > .Net
> > > > > API:
> > > > > > > interface ICache<K, V> {
> > > > > > >     V Get(K key);
> > > > > > >     IFuture<V> GetAsync(K key);
> > > > > > > }
> > > > > > >
> > > > > > > It will add 25 new methods to ICache interface and remove 2.
> But
> > > API
> > > > > will
> > > > > > > become much more friendly and natural for .Net users.
> > > > > > >
> > > > > > > Any thoughts/objections?
> > > > > > >
> > > > > > > Vladimir.
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > --
> > > > > > Pavel Tupitsyn
> > > > > > GridGain Systems, Inc.
> > > > > > www.gridgain.com
> > > > > >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > --
> > > > Pavel Tupitsyn
> > > > GridGain Systems, Inc.
> > > > www.gridgain.com
> > > >
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Nikita Ivanov <ni...@gmail.com>.
I was one of few people who reviewed this design originally and didn't see
much problem with it (it did seem contrived a bit). I now actually agree
with "below" sentiment that in retrospect it was a very bad decision and
APIs is frankly unusable IMHO.

The minute you pass instance of cache elsewhere on the call chain - this
API cannot be used sanely.

Java vs. .NET, ​API parity vs. feature parity are all good discussions to
have - but at least Java side needs to be fixed.​
--
Nikita Ivanov


On Sat, Oct 10, 2015 at 2:39 AM, Sergi Vladykin <se...@gmail.com>
wrote:

> I think IgniteAsyncSupport is a big piece of crap even in java, sync/async
> API separation definitely must be done in another way.
>
> Sergi
>
> 2015-10-10 0:40 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:
>
> > Pavel, can you explain how .NET async semantics are different from Java?
> >
> > On Fri, Oct 9, 2015 at 1:46 PM, Pavel Tupitsyn <pt...@gridgain.com>
> > wrote:
> >
> > > Hi Dmitry,
> > >
> > > > First of all, from my experience, the async APIs are used a lot less
> > > than sync
> > > ones
> > >
> > > This may be true, especially if the API is clunky.
> > > But .NET has async/await functionality which makes async code a lot
> > cleaner
> > > and easier.
> > > Good async/await support is very important, because it does not block
> > > current thread, which in turn is important for high load applications.
> > > All modern .NET APIs are async.
> > >
> > >
> > > > Secondly, the scope of this change would be huge.
> > >
> > > I don't think so. There are around 40 methods with async support in
> > current
> > > Ignite.NET.
> > > Adding their async counterparts will take a couple of hours at most.
> > > And it will simplify interop code somewhat because GetFuture goes away.
> > >
> > >
> > > > And lastly, I am against having .NET APIs different from Java APIs.
> > >
> > > Functionally they will be the same. But we should not try to bring Java
> > > semantics to .NET.
> > > Async methods in .NET are "T DoSomething()" + "Task<T>
> > DoSomethingAsync()"
> > > and we should follow this pattern so our API looks familiar to .NET
> > > community.
> > >
> > >
> > > > // Line #2
> > > > cache.Future().Get();
> > >
> > > It is cache.GetFuture<X>(). Pay attention to "X". This is very
> important:
> > > user has to specify correct return type according to return type of
> > > operation on "Line 1".
> > > Very annoying and error prone. There is even a style-checker warning
> > about
> > > such things.
> > >
> > >
> > > > 2 lines of code instead of one is not a big deal in my view.
> > >
> > > It is 2 times too much, sometimes even more. Imagine a situation where
> > you
> > > need to perform multiple async operations:
> > >
> > > cache.Get(1);
> > > var res = await cache.GetFuture<int>().ToTask();
> > >
> > > compute.Call(new MyCallable(res))
> > > var res2 = await compute.GetFuture<string>().ToTask()
> > >
> > >
> > > And with proper async API it can even be a one-liner.
> > > var res2 = await compute.CallAsync(new MyCallable(await
> > > cache.GetAsync(1)));
> > >
> > >
> > > API is the first thing a programmer sees in the new product. Let's do
> it
> > > right.
> > >
> > > Thanks,
> > >
> > > On Fri, Oct 9, 2015 at 7:17 PM, Dmitriy Setrakyan <
> dsetrakyan@apache.org
> > >
> > > wrote:
> > >
> > > > I don't think I like the proposed change.
> > > >
> > > > First of all, from my experience, the async APIs are used a lot less
> > than
> > > > sync ones, so having 2 lines of code for async calls is not a big
> deal
> > in
> > > > my view.
> > > >
> > > > Secondly, the scope of this change would be huge. We would have to
> > double
> > > > our Compute, Cache, Services, and many other APIs. Seems to me like a
> > > huge
> > > > amount of effort for a very questionable benefit, if any at all. One
> > can
> > > > argue, for example, that so many duplicate sync/async methods on all
> > the
> > > > APIs is more confusing, not less.
> > > >
> > > > And lastly, I am against having .NET APIs different from Java APIs.
> We
> > > > should have API parity as much as possible between all the platforms,
> > and
> > > > especially the .NET one, where we provide so many features.
> > > >
> > > > On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <
> ptupitsyn@gridgain.com
> > >
> > > > wrote:
> > > >
> > > > > As a .Net dev, I support this change very much.
> > > > >
> > > > > Current design with 2 method calls is not easy to use, is error
> > prone,
> > > > and
> > > > > is not familiar to .Net crowd:
> > > > >
> > > > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > > > var value = cache.Get(1);   // Is it sync or async? Can't tell from
> > > code.
> > > >
> > > > In async mode this always returns 0.
> > > > >
> > > >
> > > > Yes, you are right. But then again, async documentation clearly says
> > that
> > > > you should get a future to get the actual asynchronous result.
> > > >
> > > > The proper code here is:
> > > > -----------
> > > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > >
> > > > // Line #1
> > > > cache.Get(1);
> > > >
> > > > // Line #2
> > > > cache.Future().Get();
> > > > -----------
> > > >
> > > > 2 lines of code instead of one is not a big deal in my view.
> > > >
> > > >
> > > > > var future = cache.GetFuture<int>();   // User has to specify right
> > > > generic
> > > > > argument here. Not convenient, error prone, violates design
> > guidelines
> > > > > var actualValue = await future.ToTask();
> > > > >
> > > > >
> > > > > As opposed to:
> > > > > var value = await cache.GetAsync(1).ToTask();
> > > >
> > > >
> > > >
> > > > >
> > > > > Which is one line, obviously async, with proper generic inference.
> > > > >
> > > > >
> > > > >
> > > > > On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <
> > vozerov@gridgain.com>
> > > > > wrote:
> > > > >
> > > > > > Igniters,
> > > > > >
> > > > > > Some time ago we decided to merge sync and async methods. E.g.
> > > instead
> > > > of
> > > > > > ...
> > > > > >
> > > > > > interface Cache<K, V> {
> > > > > >     V get(K key);
> > > > > >     Future<V> getAsync(K key);
> > > > > > }
> > > > > >
> > > > > > ... we now have:
> > > > > >
> > > > > > interface Cache<K, V> extends AsyncSupport {
> > > > > >     V get(K key);
> > > > > >     Cache withAsync();
> > > > > >
> > > > > >     Future lastFuture(); // From AsyncSupport, returns future for
> > the
> > > > > last
> > > > > > operation.
> > > > > > }
> > > > > >
> > > > > > This approach is questionable. Less methods is good, and all
> > methods
> > > go
> > > > > > through JCache API. But async mode became more complex and less
> > > usable.
> > > > > > This is especially obvious in Java 8 with its lambdas and
> > > > > > CompletableFuture.
> > > > > >
> > > > > > In .Net we blindly applied this approach as well. But in this
> world
> > > > > > AsyncSupport gives even less advantages than in Java:
> > > > > > 1) There is no JCache spec here;
> > > > > > 2) Core .Net API very often use paired sync and async operations
> in
> > > the
> > > > > > same class near each other - DoMethod(), DoMethodAsync() - and
> this
> > > is
> > > > > what
> > > > > > users normally expect from async-enabled classes.
> > > > > > 3) [AsyncSupported] attribute is not highlighted in Visual
> Studio.
> > > The
> > > > > only
> > > > > > way to understand that method supports async mode is to install
> > > > ReSharper
> > > > > > or to look into source code.
> > > > > > 4) .Net has native continuations support with async/await
> keywords.
> > > Our
> > > > > API
> > > > > > doesn't support it well.
> > > > > >
> > > > > > Having said that I want to return paired "async" operations to
> .Net
> > > > API:
> > > > > > interface ICache<K, V> {
> > > > > >     V Get(K key);
> > > > > >     IFuture<V> GetAsync(K key);
> > > > > > }
> > > > > >
> > > > > > It will add 25 new methods to ICache interface and remove 2. But
> > API
> > > > will
> > > > > > become much more friendly and natural for .Net users.
> > > > > >
> > > > > > Any thoughts/objections?
> > > > > >
> > > > > > Vladimir.
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > --
> > > > > Pavel Tupitsyn
> > > > > GridGain Systems, Inc.
> > > > > www.gridgain.com
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > --
> > > Pavel Tupitsyn
> > > GridGain Systems, Inc.
> > > www.gridgain.com
> > >
> >
>

Re: .Net: separate methods for async operations.

Posted by Sergi Vladykin <se...@gmail.com>.
I think IgniteAsyncSupport is a big piece of crap even in java, sync/async
API separation definitely must be done in another way.

Sergi

2015-10-10 0:40 GMT+03:00 Dmitriy Setrakyan <ds...@apache.org>:

> Pavel, can you explain how .NET async semantics are different from Java?
>
> On Fri, Oct 9, 2015 at 1:46 PM, Pavel Tupitsyn <pt...@gridgain.com>
> wrote:
>
> > Hi Dmitry,
> >
> > > First of all, from my experience, the async APIs are used a lot less
> > than sync
> > ones
> >
> > This may be true, especially if the API is clunky.
> > But .NET has async/await functionality which makes async code a lot
> cleaner
> > and easier.
> > Good async/await support is very important, because it does not block
> > current thread, which in turn is important for high load applications.
> > All modern .NET APIs are async.
> >
> >
> > > Secondly, the scope of this change would be huge.
> >
> > I don't think so. There are around 40 methods with async support in
> current
> > Ignite.NET.
> > Adding their async counterparts will take a couple of hours at most.
> > And it will simplify interop code somewhat because GetFuture goes away.
> >
> >
> > > And lastly, I am against having .NET APIs different from Java APIs.
> >
> > Functionally they will be the same. But we should not try to bring Java
> > semantics to .NET.
> > Async methods in .NET are "T DoSomething()" + "Task<T>
> DoSomethingAsync()"
> > and we should follow this pattern so our API looks familiar to .NET
> > community.
> >
> >
> > > // Line #2
> > > cache.Future().Get();
> >
> > It is cache.GetFuture<X>(). Pay attention to "X". This is very important:
> > user has to specify correct return type according to return type of
> > operation on "Line 1".
> > Very annoying and error prone. There is even a style-checker warning
> about
> > such things.
> >
> >
> > > 2 lines of code instead of one is not a big deal in my view.
> >
> > It is 2 times too much, sometimes even more. Imagine a situation where
> you
> > need to perform multiple async operations:
> >
> > cache.Get(1);
> > var res = await cache.GetFuture<int>().ToTask();
> >
> > compute.Call(new MyCallable(res))
> > var res2 = await compute.GetFuture<string>().ToTask()
> >
> >
> > And with proper async API it can even be a one-liner.
> > var res2 = await compute.CallAsync(new MyCallable(await
> > cache.GetAsync(1)));
> >
> >
> > API is the first thing a programmer sees in the new product. Let's do it
> > right.
> >
> > Thanks,
> >
> > On Fri, Oct 9, 2015 at 7:17 PM, Dmitriy Setrakyan <dsetrakyan@apache.org
> >
> > wrote:
> >
> > > I don't think I like the proposed change.
> > >
> > > First of all, from my experience, the async APIs are used a lot less
> than
> > > sync ones, so having 2 lines of code for async calls is not a big deal
> in
> > > my view.
> > >
> > > Secondly, the scope of this change would be huge. We would have to
> double
> > > our Compute, Cache, Services, and many other APIs. Seems to me like a
> > huge
> > > amount of effort for a very questionable benefit, if any at all. One
> can
> > > argue, for example, that so many duplicate sync/async methods on all
> the
> > > APIs is more confusing, not less.
> > >
> > > And lastly, I am against having .NET APIs different from Java APIs. We
> > > should have API parity as much as possible between all the platforms,
> and
> > > especially the .NET one, where we provide so many features.
> > >
> > > On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <ptupitsyn@gridgain.com
> >
> > > wrote:
> > >
> > > > As a .Net dev, I support this change very much.
> > > >
> > > > Current design with 2 method calls is not easy to use, is error
> prone,
> > > and
> > > > is not familiar to .Net crowd:
> > > >
> > > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > > var value = cache.Get(1);   // Is it sync or async? Can't tell from
> > code.
> > >
> > > In async mode this always returns 0.
> > > >
> > >
> > > Yes, you are right. But then again, async documentation clearly says
> that
> > > you should get a future to get the actual asynchronous result.
> > >
> > > The proper code here is:
> > > -----------
> > > var cache = ignite.GetCache<int, int>().WithAsync();
> > >
> > > // Line #1
> > > cache.Get(1);
> > >
> > > // Line #2
> > > cache.Future().Get();
> > > -----------
> > >
> > > 2 lines of code instead of one is not a big deal in my view.
> > >
> > >
> > > > var future = cache.GetFuture<int>();   // User has to specify right
> > > generic
> > > > argument here. Not convenient, error prone, violates design
> guidelines
> > > > var actualValue = await future.ToTask();
> > > >
> > > >
> > > > As opposed to:
> > > > var value = await cache.GetAsync(1).ToTask();
> > >
> > >
> > >
> > > >
> > > > Which is one line, obviously async, with proper generic inference.
> > > >
> > > >
> > > >
> > > > On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <
> vozerov@gridgain.com>
> > > > wrote:
> > > >
> > > > > Igniters,
> > > > >
> > > > > Some time ago we decided to merge sync and async methods. E.g.
> > instead
> > > of
> > > > > ...
> > > > >
> > > > > interface Cache<K, V> {
> > > > >     V get(K key);
> > > > >     Future<V> getAsync(K key);
> > > > > }
> > > > >
> > > > > ... we now have:
> > > > >
> > > > > interface Cache<K, V> extends AsyncSupport {
> > > > >     V get(K key);
> > > > >     Cache withAsync();
> > > > >
> > > > >     Future lastFuture(); // From AsyncSupport, returns future for
> the
> > > > last
> > > > > operation.
> > > > > }
> > > > >
> > > > > This approach is questionable. Less methods is good, and all
> methods
> > go
> > > > > through JCache API. But async mode became more complex and less
> > usable.
> > > > > This is especially obvious in Java 8 with its lambdas and
> > > > > CompletableFuture.
> > > > >
> > > > > In .Net we blindly applied this approach as well. But in this world
> > > > > AsyncSupport gives even less advantages than in Java:
> > > > > 1) There is no JCache spec here;
> > > > > 2) Core .Net API very often use paired sync and async operations in
> > the
> > > > > same class near each other - DoMethod(), DoMethodAsync() - and this
> > is
> > > > what
> > > > > users normally expect from async-enabled classes.
> > > > > 3) [AsyncSupported] attribute is not highlighted in Visual Studio.
> > The
> > > > only
> > > > > way to understand that method supports async mode is to install
> > > ReSharper
> > > > > or to look into source code.
> > > > > 4) .Net has native continuations support with async/await keywords.
> > Our
> > > > API
> > > > > doesn't support it well.
> > > > >
> > > > > Having said that I want to return paired "async" operations to .Net
> > > API:
> > > > > interface ICache<K, V> {
> > > > >     V Get(K key);
> > > > >     IFuture<V> GetAsync(K key);
> > > > > }
> > > > >
> > > > > It will add 25 new methods to ICache interface and remove 2. But
> API
> > > will
> > > > > become much more friendly and natural for .Net users.
> > > > >
> > > > > Any thoughts/objections?
> > > > >
> > > > > Vladimir.
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > --
> > > > Pavel Tupitsyn
> > > > GridGain Systems, Inc.
> > > > www.gridgain.com
> > > >
> > >
> >
> >
> >
> > --
> > --
> > Pavel Tupitsyn
> > GridGain Systems, Inc.
> > www.gridgain.com
> >
>

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
Pavel, can you explain how .NET async semantics are different from Java?

On Fri, Oct 9, 2015 at 1:46 PM, Pavel Tupitsyn <pt...@gridgain.com>
wrote:

> Hi Dmitry,
>
> > First of all, from my experience, the async APIs are used a lot less
> than sync
> ones
>
> This may be true, especially if the API is clunky.
> But .NET has async/await functionality which makes async code a lot cleaner
> and easier.
> Good async/await support is very important, because it does not block
> current thread, which in turn is important for high load applications.
> All modern .NET APIs are async.
>
>
> > Secondly, the scope of this change would be huge.
>
> I don't think so. There are around 40 methods with async support in current
> Ignite.NET.
> Adding their async counterparts will take a couple of hours at most.
> And it will simplify interop code somewhat because GetFuture goes away.
>
>
> > And lastly, I am against having .NET APIs different from Java APIs.
>
> Functionally they will be the same. But we should not try to bring Java
> semantics to .NET.
> Async methods in .NET are "T DoSomething()" + "Task<T> DoSomethingAsync()"
> and we should follow this pattern so our API looks familiar to .NET
> community.
>
>
> > // Line #2
> > cache.Future().Get();
>
> It is cache.GetFuture<X>(). Pay attention to "X". This is very important:
> user has to specify correct return type according to return type of
> operation on "Line 1".
> Very annoying and error prone. There is even a style-checker warning about
> such things.
>
>
> > 2 lines of code instead of one is not a big deal in my view.
>
> It is 2 times too much, sometimes even more. Imagine a situation where you
> need to perform multiple async operations:
>
> cache.Get(1);
> var res = await cache.GetFuture<int>().ToTask();
>
> compute.Call(new MyCallable(res))
> var res2 = await compute.GetFuture<string>().ToTask()
>
>
> And with proper async API it can even be a one-liner.
> var res2 = await compute.CallAsync(new MyCallable(await
> cache.GetAsync(1)));
>
>
> API is the first thing a programmer sees in the new product. Let's do it
> right.
>
> Thanks,
>
> On Fri, Oct 9, 2015 at 7:17 PM, Dmitriy Setrakyan <ds...@apache.org>
> wrote:
>
> > I don't think I like the proposed change.
> >
> > First of all, from my experience, the async APIs are used a lot less than
> > sync ones, so having 2 lines of code for async calls is not a big deal in
> > my view.
> >
> > Secondly, the scope of this change would be huge. We would have to double
> > our Compute, Cache, Services, and many other APIs. Seems to me like a
> huge
> > amount of effort for a very questionable benefit, if any at all. One can
> > argue, for example, that so many duplicate sync/async methods on all the
> > APIs is more confusing, not less.
> >
> > And lastly, I am against having .NET APIs different from Java APIs. We
> > should have API parity as much as possible between all the platforms, and
> > especially the .NET one, where we provide so many features.
> >
> > On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <pt...@gridgain.com>
> > wrote:
> >
> > > As a .Net dev, I support this change very much.
> > >
> > > Current design with 2 method calls is not easy to use, is error prone,
> > and
> > > is not familiar to .Net crowd:
> > >
> > > var cache = ignite.GetCache<int, int>().WithAsync();
> > > var value = cache.Get(1);   // Is it sync or async? Can't tell from
> code.
> >
> > In async mode this always returns 0.
> > >
> >
> > Yes, you are right. But then again, async documentation clearly says that
> > you should get a future to get the actual asynchronous result.
> >
> > The proper code here is:
> > -----------
> > var cache = ignite.GetCache<int, int>().WithAsync();
> >
> > // Line #1
> > cache.Get(1);
> >
> > // Line #2
> > cache.Future().Get();
> > -----------
> >
> > 2 lines of code instead of one is not a big deal in my view.
> >
> >
> > > var future = cache.GetFuture<int>();   // User has to specify right
> > generic
> > > argument here. Not convenient, error prone, violates design guidelines
> > > var actualValue = await future.ToTask();
> > >
> > >
> > > As opposed to:
> > > var value = await cache.GetAsync(1).ToTask();
> >
> >
> >
> > >
> > > Which is one line, obviously async, with proper generic inference.
> > >
> > >
> > >
> > > On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <vo...@gridgain.com>
> > > wrote:
> > >
> > > > Igniters,
> > > >
> > > > Some time ago we decided to merge sync and async methods. E.g.
> instead
> > of
> > > > ...
> > > >
> > > > interface Cache<K, V> {
> > > >     V get(K key);
> > > >     Future<V> getAsync(K key);
> > > > }
> > > >
> > > > ... we now have:
> > > >
> > > > interface Cache<K, V> extends AsyncSupport {
> > > >     V get(K key);
> > > >     Cache withAsync();
> > > >
> > > >     Future lastFuture(); // From AsyncSupport, returns future for the
> > > last
> > > > operation.
> > > > }
> > > >
> > > > This approach is questionable. Less methods is good, and all methods
> go
> > > > through JCache API. But async mode became more complex and less
> usable.
> > > > This is especially obvious in Java 8 with its lambdas and
> > > > CompletableFuture.
> > > >
> > > > In .Net we blindly applied this approach as well. But in this world
> > > > AsyncSupport gives even less advantages than in Java:
> > > > 1) There is no JCache spec here;
> > > > 2) Core .Net API very often use paired sync and async operations in
> the
> > > > same class near each other - DoMethod(), DoMethodAsync() - and this
> is
> > > what
> > > > users normally expect from async-enabled classes.
> > > > 3) [AsyncSupported] attribute is not highlighted in Visual Studio.
> The
> > > only
> > > > way to understand that method supports async mode is to install
> > ReSharper
> > > > or to look into source code.
> > > > 4) .Net has native continuations support with async/await keywords.
> Our
> > > API
> > > > doesn't support it well.
> > > >
> > > > Having said that I want to return paired "async" operations to .Net
> > API:
> > > > interface ICache<K, V> {
> > > >     V Get(K key);
> > > >     IFuture<V> GetAsync(K key);
> > > > }
> > > >
> > > > It will add 25 new methods to ICache interface and remove 2. But API
> > will
> > > > become much more friendly and natural for .Net users.
> > > >
> > > > Any thoughts/objections?
> > > >
> > > > Vladimir.
> > > >
> > >
> > >
> > >
> > > --
> > > --
> > > Pavel Tupitsyn
> > > GridGain Systems, Inc.
> > > www.gridgain.com
> > >
> >
>
>
>
> --
> --
> Pavel Tupitsyn
> GridGain Systems, Inc.
> www.gridgain.com
>

Re: .Net: separate methods for async operations.

Posted by Yakov Zhdanov <yz...@apache.org>.
> 2 lines of code instead of one is not a big deal in my view.

>It is 2 times too much, sometimes even more. Imagine a situation where you
>need to perform multiple async operations:

>cache.Get(1);
>var res = await cache.GetFuture<int>().ToTask();

>compute.Call(new MyCallable(res))
>var res2 = await compute.GetFuture<string>().ToTask()


>And with proper async API it can even be a one-liner.
>var res2 = await compute.CallAsync(new MyCallable(await
cache.GetAsync(1)));

It seems that this example does not show the proper usecase for async APIs.
If it is reimplemented in sync manner it would become clearer and,
probably, faster. What is the purpose of async here if I wait in current
thread?

--Yakov

Re: .Net: separate methods for async operations.

Posted by Pavel Tupitsyn <pt...@gridgain.com>.
Hi Dmitry,

> First of all, from my experience, the async APIs are used a lot less than sync
ones

This may be true, especially if the API is clunky.
But .NET has async/await functionality which makes async code a lot cleaner
and easier.
Good async/await support is very important, because it does not block
current thread, which in turn is important for high load applications.
All modern .NET APIs are async.


> Secondly, the scope of this change would be huge.

I don't think so. There are around 40 methods with async support in current
Ignite.NET.
Adding their async counterparts will take a couple of hours at most.
And it will simplify interop code somewhat because GetFuture goes away.


> And lastly, I am against having .NET APIs different from Java APIs.

Functionally they will be the same. But we should not try to bring Java
semantics to .NET.
Async methods in .NET are "T DoSomething()" + "Task<T> DoSomethingAsync()"
and we should follow this pattern so our API looks familiar to .NET
community.


> // Line #2
> cache.Future().Get();

It is cache.GetFuture<X>(). Pay attention to "X". This is very important:
user has to specify correct return type according to return type of
operation on "Line 1".
Very annoying and error prone. There is even a style-checker warning about
such things.


> 2 lines of code instead of one is not a big deal in my view.

It is 2 times too much, sometimes even more. Imagine a situation where you
need to perform multiple async operations:

cache.Get(1);
var res = await cache.GetFuture<int>().ToTask();

compute.Call(new MyCallable(res))
var res2 = await compute.GetFuture<string>().ToTask()


And with proper async API it can even be a one-liner.
var res2 = await compute.CallAsync(new MyCallable(await cache.GetAsync(1)));


API is the first thing a programmer sees in the new product. Let's do it
right.

Thanks,

On Fri, Oct 9, 2015 at 7:17 PM, Dmitriy Setrakyan <ds...@apache.org>
wrote:

> I don't think I like the proposed change.
>
> First of all, from my experience, the async APIs are used a lot less than
> sync ones, so having 2 lines of code for async calls is not a big deal in
> my view.
>
> Secondly, the scope of this change would be huge. We would have to double
> our Compute, Cache, Services, and many other APIs. Seems to me like a huge
> amount of effort for a very questionable benefit, if any at all. One can
> argue, for example, that so many duplicate sync/async methods on all the
> APIs is more confusing, not less.
>
> And lastly, I am against having .NET APIs different from Java APIs. We
> should have API parity as much as possible between all the platforms, and
> especially the .NET one, where we provide so many features.
>
> On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <pt...@gridgain.com>
> wrote:
>
> > As a .Net dev, I support this change very much.
> >
> > Current design with 2 method calls is not easy to use, is error prone,
> and
> > is not familiar to .Net crowd:
> >
> > var cache = ignite.GetCache<int, int>().WithAsync();
> > var value = cache.Get(1);   // Is it sync or async? Can't tell from code.
>
> In async mode this always returns 0.
> >
>
> Yes, you are right. But then again, async documentation clearly says that
> you should get a future to get the actual asynchronous result.
>
> The proper code here is:
> -----------
> var cache = ignite.GetCache<int, int>().WithAsync();
>
> // Line #1
> cache.Get(1);
>
> // Line #2
> cache.Future().Get();
> -----------
>
> 2 lines of code instead of one is not a big deal in my view.
>
>
> > var future = cache.GetFuture<int>();   // User has to specify right
> generic
> > argument here. Not convenient, error prone, violates design guidelines
> > var actualValue = await future.ToTask();
> >
> >
> > As opposed to:
> > var value = await cache.GetAsync(1).ToTask();
>
>
>
> >
> > Which is one line, obviously async, with proper generic inference.
> >
> >
> >
> > On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <vo...@gridgain.com>
> > wrote:
> >
> > > Igniters,
> > >
> > > Some time ago we decided to merge sync and async methods. E.g. instead
> of
> > > ...
> > >
> > > interface Cache<K, V> {
> > >     V get(K key);
> > >     Future<V> getAsync(K key);
> > > }
> > >
> > > ... we now have:
> > >
> > > interface Cache<K, V> extends AsyncSupport {
> > >     V get(K key);
> > >     Cache withAsync();
> > >
> > >     Future lastFuture(); // From AsyncSupport, returns future for the
> > last
> > > operation.
> > > }
> > >
> > > This approach is questionable. Less methods is good, and all methods go
> > > through JCache API. But async mode became more complex and less usable.
> > > This is especially obvious in Java 8 with its lambdas and
> > > CompletableFuture.
> > >
> > > In .Net we blindly applied this approach as well. But in this world
> > > AsyncSupport gives even less advantages than in Java:
> > > 1) There is no JCache spec here;
> > > 2) Core .Net API very often use paired sync and async operations in the
> > > same class near each other - DoMethod(), DoMethodAsync() - and this is
> > what
> > > users normally expect from async-enabled classes.
> > > 3) [AsyncSupported] attribute is not highlighted in Visual Studio. The
> > only
> > > way to understand that method supports async mode is to install
> ReSharper
> > > or to look into source code.
> > > 4) .Net has native continuations support with async/await keywords. Our
> > API
> > > doesn't support it well.
> > >
> > > Having said that I want to return paired "async" operations to .Net
> API:
> > > interface ICache<K, V> {
> > >     V Get(K key);
> > >     IFuture<V> GetAsync(K key);
> > > }
> > >
> > > It will add 25 new methods to ICache interface and remove 2. But API
> will
> > > become much more friendly and natural for .Net users.
> > >
> > > Any thoughts/objections?
> > >
> > > Vladimir.
> > >
> >
> >
> >
> > --
> > --
> > Pavel Tupitsyn
> > GridGain Systems, Inc.
> > www.gridgain.com
> >
>



-- 
-- 
Pavel Tupitsyn
GridGain Systems, Inc.
www.gridgain.com

Re: .Net: separate methods for async operations.

Posted by Dmitriy Setrakyan <ds...@apache.org>.
I don't think I like the proposed change.

First of all, from my experience, the async APIs are used a lot less than
sync ones, so having 2 lines of code for async calls is not a big deal in
my view.

Secondly, the scope of this change would be huge. We would have to double
our Compute, Cache, Services, and many other APIs. Seems to me like a huge
amount of effort for a very questionable benefit, if any at all. One can
argue, for example, that so many duplicate sync/async methods on all the
APIs is more confusing, not less.

And lastly, I am against having .NET APIs different from Java APIs. We
should have API parity as much as possible between all the platforms, and
especially the .NET one, where we provide so many features.

On Fri, Oct 9, 2015 at 7:05 AM, Pavel Tupitsyn <pt...@gridgain.com>
wrote:

> As a .Net dev, I support this change very much.
>
> Current design with 2 method calls is not easy to use, is error prone, and
> is not familiar to .Net crowd:
>
> var cache = ignite.GetCache<int, int>().WithAsync();
> var value = cache.Get(1);   // Is it sync or async? Can't tell from code.

In async mode this always returns 0.
>

Yes, you are right. But then again, async documentation clearly says that
you should get a future to get the actual asynchronous result.

The proper code here is:
-----------
var cache = ignite.GetCache<int, int>().WithAsync();

// Line #1
cache.Get(1);

// Line #2
cache.Future().Get();
-----------

2 lines of code instead of one is not a big deal in my view.


> var future = cache.GetFuture<int>();   // User has to specify right generic
> argument here. Not convenient, error prone, violates design guidelines
> var actualValue = await future.ToTask();
>
>
> As opposed to:
> var value = await cache.GetAsync(1).ToTask();



>
> Which is one line, obviously async, with proper generic inference.
>
>
>
> On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <vo...@gridgain.com>
> wrote:
>
> > Igniters,
> >
> > Some time ago we decided to merge sync and async methods. E.g. instead of
> > ...
> >
> > interface Cache<K, V> {
> >     V get(K key);
> >     Future<V> getAsync(K key);
> > }
> >
> > ... we now have:
> >
> > interface Cache<K, V> extends AsyncSupport {
> >     V get(K key);
> >     Cache withAsync();
> >
> >     Future lastFuture(); // From AsyncSupport, returns future for the
> last
> > operation.
> > }
> >
> > This approach is questionable. Less methods is good, and all methods go
> > through JCache API. But async mode became more complex and less usable.
> > This is especially obvious in Java 8 with its lambdas and
> > CompletableFuture.
> >
> > In .Net we blindly applied this approach as well. But in this world
> > AsyncSupport gives even less advantages than in Java:
> > 1) There is no JCache spec here;
> > 2) Core .Net API very often use paired sync and async operations in the
> > same class near each other - DoMethod(), DoMethodAsync() - and this is
> what
> > users normally expect from async-enabled classes.
> > 3) [AsyncSupported] attribute is not highlighted in Visual Studio. The
> only
> > way to understand that method supports async mode is to install ReSharper
> > or to look into source code.
> > 4) .Net has native continuations support with async/await keywords. Our
> API
> > doesn't support it well.
> >
> > Having said that I want to return paired "async" operations to .Net API:
> > interface ICache<K, V> {
> >     V Get(K key);
> >     IFuture<V> GetAsync(K key);
> > }
> >
> > It will add 25 new methods to ICache interface and remove 2. But API will
> > become much more friendly and natural for .Net users.
> >
> > Any thoughts/objections?
> >
> > Vladimir.
> >
>
>
>
> --
> --
> Pavel Tupitsyn
> GridGain Systems, Inc.
> www.gridgain.com
>

Re: .Net: separate methods for async operations.

Posted by Pavel Tupitsyn <pt...@gridgain.com>.
As a .Net dev, I support this change very much.

Current design with 2 method calls is not easy to use, is error prone, and
is not familiar to .Net crowd:

var cache = ignite.GetCache<int, int>().WithAsync();
var value = cache.Get(1);   // Is it sync or async? Can't tell from code.
In async mode this always returns 0.
var future = cache.GetFuture<int>();   // User has to specify right generic
argument here. Not convenient, error prone, violates design guidelines
var actualValue = await future.ToTask();


As opposed to:
var value = await cache.GetAsync(1).ToTask();

Which is one line, obviously async, with proper generic inference.



On Fri, Oct 9, 2015 at 4:47 PM, Vladimir Ozerov <vo...@gridgain.com>
wrote:

> Igniters,
>
> Some time ago we decided to merge sync and async methods. E.g. instead of
> ...
>
> interface Cache<K, V> {
>     V get(K key);
>     Future<V> getAsync(K key);
> }
>
> ... we now have:
>
> interface Cache<K, V> extends AsyncSupport {
>     V get(K key);
>     Cache withAsync();
>
>     Future lastFuture(); // From AsyncSupport, returns future for the last
> operation.
> }
>
> This approach is questionable. Less methods is good, and all methods go
> through JCache API. But async mode became more complex and less usable.
> This is especially obvious in Java 8 with its lambdas and
> CompletableFuture.
>
> In .Net we blindly applied this approach as well. But in this world
> AsyncSupport gives even less advantages than in Java:
> 1) There is no JCache spec here;
> 2) Core .Net API very often use paired sync and async operations in the
> same class near each other - DoMethod(), DoMethodAsync() - and this is what
> users normally expect from async-enabled classes.
> 3) [AsyncSupported] attribute is not highlighted in Visual Studio. The only
> way to understand that method supports async mode is to install ReSharper
> or to look into source code.
> 4) .Net has native continuations support with async/await keywords. Our API
> doesn't support it well.
>
> Having said that I want to return paired "async" operations to .Net API:
> interface ICache<K, V> {
>     V Get(K key);
>     IFuture<V> GetAsync(K key);
> }
>
> It will add 25 new methods to ICache interface and remove 2. But API will
> become much more friendly and natural for .Net users.
>
> Any thoughts/objections?
>
> Vladimir.
>



-- 
-- 
Pavel Tupitsyn
GridGain Systems, Inc.
www.gridgain.com