.Net: separate methods for async operations.

classic Classic list List threaded Threaded
32 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Sergi
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 <[hidden email]>:

> On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <[hidden email]>
> 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 <
> [hidden email]>
> > 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 <[hidden email]>:
> > >
> > > > 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 <
> [hidden email]
> > >
> > > > 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 <
> [hidden email]>
> > > > > wrote:
> > > > >
> > > > > > Is current thread blocked until "await" instruction is completed
> in
> > > > > > parallel thread?
> > > > > >
> > > > > > --Yakov
> > > > > >
> > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[hidden email]
> >:
> > > > > >
> > > > > > > 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 <
> > > > > > [hidden email]
> > > > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > [hidden email]
> > > > > > >
> > > > > > > > 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?
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Vladimir Ozerov
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 <[hidden email]>
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 <[hidden email]>:
>
> > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <[hidden email]>
> > 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 <
> > [hidden email]>
> > > 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 <[hidden email]
> >:
> > > >
> > > > > 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 <
> > [hidden email]
> > > >
> > > > > 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 <
> > [hidden email]>
> > > > > > wrote:
> > > > > >
> > > > > > > Is current thread blocked until "await" instruction is
> completed
> > in
> > > > > > > parallel thread?
> > > > > > >
> > > > > > > --Yakov
> > > > > > >
> > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> [hidden email]
> > >:
> > > > > > >
> > > > > > > > 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 <
> > > > > > > [hidden email]
> > > > > > > > >
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > [hidden email]
> > > > > > > >
> > > > > > > > > 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?
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

dsetrakyan
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 <[hidden email]>
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 <[hidden email]>
> 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 <[hidden email]>:
> >
> > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> [hidden email]>
> > > 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 <
> > > [hidden email]>
> > > > 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 <
> [hidden email]
> > >:
> > > > >
> > > > > > 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 <
> > > [hidden email]
> > > > >
> > > > > > 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 <
> > > [hidden email]>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Is current thread blocked until "await" instruction is
> > completed
> > > in
> > > > > > > > parallel thread?
> > > > > > > >
> > > > > > > > --Yakov
> > > > > > > >
> > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > [hidden email]
> > > >:
> > > > > > > >
> > > > > > > > > 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 <
> > > > > > > > [hidden email]
> > > > > > > > > >
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > [hidden email]
> > > > > > > > >
> > > > > > > > > > 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?
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

nivanov
In reply to this post by dsetrakyan
+1 on Sergey's idea too.

--
Nikita Ivanov


On Mon, Oct 12, 2015 at 10:10 AM, Dmitriy Setrakyan <[hidden email]>
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 <[hidden email]>
> 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 <[hidden email]>:
> >
> > > 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 <[hidden email]
> >
> > > 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 <[hidden email]>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[hidden email]>:
> > > > >
> > > > > > 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 <
> > > > > [hidden email]
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > [hidden email]
> > > > > >
> > > > > > > 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?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Vladimir Ozerov
In reply to this post by dsetrakyan
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 <[hidden email]>
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 <[hidden email]>
> 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 <
> [hidden email]>
> > 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 <[hidden email]>:
> > >
> > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > [hidden email]>
> > > > 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 <
> > > > [hidden email]>
> > > > > 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 <
> > [hidden email]
> > > >:
> > > > > >
> > > > > > > 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 <
> > > > [hidden email]
> > > > > >
> > > > > > > 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 <
> > > > [hidden email]>
> > > > > > > > wrote:
> > > > > > > >
> > > > > > > > > Is current thread blocked until "await" instruction is
> > > completed
> > > > in
> > > > > > > > > parallel thread?
> > > > > > > > >
> > > > > > > > > --Yakov
> > > > > > > > >
> > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > [hidden email]
> > > > >:
> > > > > > > > >
> > > > > > > > > > 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 <
> > > > > > > > > [hidden email]
> > > > > > > > > > >
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > [hidden email]
> > > > > > > > > >
> > > > > > > > > > > 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?
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Pavel Tupitsyn-3
> 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 <[hidden email]>
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 <[hidden email]
> >
> 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 <[hidden email]>
> > 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 <
> > [hidden email]>
> > > 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 <[hidden email]
> >:
> > > >
> > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > [hidden email]>
> > > > > 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 <
> > > > > [hidden email]>
> > > > > > 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 <
> > > [hidden email]
> > > > >:
> > > > > > >
> > > > > > > > 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 <
> > > > > [hidden email]
> > > > > > >
> > > > > > > > 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 <
> > > > > [hidden email]>
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > completed
> > > > > in
> > > > > > > > > > parallel thread?
> > > > > > > > > >
> > > > > > > > > > --Yakov
> > > > > > > > > >
> > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > [hidden email]
> > > > > >:
> > > > > > > > > >
> > > > > > > > > > > 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 <
> > > > > > > > > > [hidden email]
> > > > > > > > > > > >
> > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > [hidden email]
> > > > > > > > > > >
> > > > > > > > > > > > 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
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

dsetrakyan
In reply to this post by Vladimir Ozerov
On Mon, Oct 12, 2015 at 10:56 PM, Vladimir Ozerov <[hidden email]>
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 <[hidden email]
> >
> 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 <[hidden email]>
> > 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 <
> > [hidden email]>
> > > 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 <[hidden email]
> >:
> > > >
> > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > [hidden email]>
> > > > > 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 <
> > > > > [hidden email]>
> > > > > > 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 <
> > > [hidden email]
> > > > >:
> > > > > > >
> > > > > > > > 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 <
> > > > > [hidden email]
> > > > > > >
> > > > > > > > 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 <
> > > > > [hidden email]>
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > completed
> > > > > in
> > > > > > > > > > parallel thread?
> > > > > > > > > >
> > > > > > > > > > --Yakov
> > > > > > > > > >
> > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > [hidden email]
> > > > > >:
> > > > > > > > > >
> > > > > > > > > > > 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 <
> > > > > > > > > > [hidden email]
> > > > > > > > > > > >
> > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > [hidden email]
> > > > > > > > > > >
> > > > > > > > > > > > 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?
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

dsetrakyan
In reply to this post by Pavel Tupitsyn-3
On Tue, Oct 13, 2015 at 1:54 AM, Pavel Tupitsyn <[hidden email]>
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 <[hidden email]>
> 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 <
> [hidden email]
> > >
> > 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 <
> [hidden email]>
> > > 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 <
> > > [hidden email]>
> > > > 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 <
> [hidden email]
> > >:
> > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > > [hidden email]>
> > > > > > 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 <
> > > > > > [hidden email]>
> > > > > > > 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 <
> > > > [hidden email]
> > > > > >:
> > > > > > > >
> > > > > > > > > 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 <
> > > > > > [hidden email]
> > > > > > > >
> > > > > > > > > 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 <
> > > > > > [hidden email]>
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > > completed
> > > > > > in
> > > > > > > > > > > parallel thread?
> > > > > > > > > > >
> > > > > > > > > > > --Yakov
> > > > > > > > > > >
> > > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > > [hidden email]
> > > > > > >:
> > > > > > > > > > >
> > > > > > > > > > > > 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 <
> > > > > > > > > > > [hidden email]
> > > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > > [hidden email]
> > > > > > > > > > > >
> > > > > > > > > > > > > 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
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Vladimir Ozerov
In reply to this post by dsetrakyan
> 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 <[hidden email]>
wrote:

> On Mon, Oct 12, 2015 at 10:56 PM, Vladimir Ozerov <[hidden email]>
> 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 <
> [hidden email]
> > >
> > 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 <
> [hidden email]>
> > > 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 <
> > > [hidden email]>
> > > > 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 <
> [hidden email]
> > >:
> > > > >
> > > > > > On Mon, Oct 12, 2015 at 10:15 AM, Vladimir Ozerov <
> > > > [hidden email]>
> > > > > > 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 <
> > > > > > [hidden email]>
> > > > > > > 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 <
> > > > [hidden email]
> > > > > >:
> > > > > > > >
> > > > > > > > > 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 <
> > > > > > [hidden email]
> > > > > > > >
> > > > > > > > > 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 <
> > > > > > [hidden email]>
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Is current thread blocked until "await" instruction is
> > > > > completed
> > > > > > in
> > > > > > > > > > > parallel thread?
> > > > > > > > > > >
> > > > > > > > > > > --Yakov
> > > > > > > > > > >
> > > > > > > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <
> > > > > [hidden email]
> > > > > > >:
> > > > > > > > > > >
> > > > > > > > > > > > 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 <
> > > > > > > > > > > [hidden email]
> > > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > > > > > > [hidden email]
> > > > > > > > > > > >
> > > > > > > > > > > > > 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?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Fwd: .Net: separate methods for async operations.

Raul Kripalani
In reply to this post by Sergi
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 <[hidden email]>
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 <[hidden email]>:
>
> > 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 <[hidden email]>
> > 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 <[hidden email]>
> > > wrote:
> > >
> > > > Is current thread blocked until "await" instruction is completed in
> > > > parallel thread?
> > > >
> > > > --Yakov
> > > >
> > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[hidden email]>:
> > > >
> > > > > 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 <
> > > > [hidden email]
> > > > > >
> > > > > wrote:
> > > > >
> > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > [hidden email]
> > > > >
> > > > > > 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?
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

dsetrakyan
On Tue, Oct 13, 2015 at 9:19 AM, Raul Kripalani <[hidden email]> 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 <[hidden email]>
> 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 <[hidden email]>:
> >
> > > 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 <[hidden email]
> >
> > > 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 <[hidden email]>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[hidden email]>:
> > > > >
> > > > > > 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 <
> > > > > [hidden email]
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > [hidden email]
> > > > > >
> > > > > > > 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?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: .Net: separate methods for async operations.

Sergi
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 <[hidden email]>:

> On Tue, Oct 13, 2015 at 9:19 AM, Raul Kripalani <[hidden email]> 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 <
> [hidden email]>
> > 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 <[hidden email]>:
> > >
> > > > 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 <
> [hidden email]
> > >
> > > > 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 <
> [hidden email]>
> > > > > wrote:
> > > > >
> > > > > > Is current thread blocked until "await" instruction is completed
> in
> > > > > > parallel thread?
> > > > > >
> > > > > > --Yakov
> > > > > >
> > > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[hidden email]
> >:
> > > > > >
> > > > > > > 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 <
> > > > > > [hidden email]
> > > > > > > >
> > > > > > > wrote:
> > > > > > >
> > > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > > [hidden email]
> > > > > > >
> > > > > > > > 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?
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
12