Vladimir,
I don't see why it is an issue that not all Cache methods will have async
variants,
AsyncCache just will have only needed async methods.
Also I don't see why we need backward transformation from async to sync,
as a user you should always pass IgniteCache everywhere and
use async as needed like *cache.async().get("myKey")*.
I agree that IgniteCache.get() != AsyncCache.get().get(), I was a bit too
optimistic
about it, but it is not a show stopper as well, just a bit more efforts
will be needed.
Anyways these sync and async implementations will follow the same patterns
all the time.
As for platforms consistency I'm for it where it makes sense, but I believe
you know better :)
Sergi
2015-10-12 20:15 GMT+03:00 Vladimir Ozerov <[email protected]>:
> Sergi,
>
> Pavel and I thought about this. The problem with this approach is that not
> all methods are async. E.g. name(), lock(K), iterator(), etc.. So you
> should either mix sync and async methods in AsyncCache still, or expose
> only async methods. In the latter case we will require backwards
> transformation: IgniteCache AsyncCache.sync().
>
> Looks like there is no ideal solutions. We should just pick one.
>
> Also please note that IgniteCache.get() != AsyncCache.get().get(). Sync and
> async operations do not go through the same path in general case. Otherwise
> sync operations could be blocked by async operations due to exhausted
> semaphore. We found a deadlock in IGFS because of this several days ago.
>
> Consistency between platforms should have minimal priority. .Net and Java
> are very different. For example we cannot even have "V Get(K)" method in
> .Net cache. Instead we have "V TryGet(K, out bool)" because .Net supports
> structs and have full generics support and naive Java approach simply
> doesn't work here. Base concepts must be the same across platforms, but
> methods signatures and grouping will be different.
>
>
>
>
> On Mon, Oct 12, 2015 at 7:53 PM, Sergi Vladykin <[email protected]>
> 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 <[email protected]>:
> >
> > > 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 <[email protected]
> >
> > > 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 <[email protected]>
> > > > wrote:
> > > >
> > > > > Is current thread blocked until "await" instruction is completed in
> > > > > parallel thread?
> > > > >
> > > > > --Yakov
> > > > >
> > > > > 2015-10-12 10:41 GMT+03:00 Vladimir Ozerov <[email protected]>:
> > > > >
> > > > > > 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 <
> > > > > [email protected]
> > > > > > >
> > > > > > wrote:
> > > > > >
> > > > > > > On Sun, Oct 11, 2015 at 3:42 AM, Vladimir Ozerov <
> > > > [email protected]
> > > > > >
> > > > > > > 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?
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>