[infinispan-dev] Ditching ASYNC modes for REPL/DIST/INV/CacheStores?

Galder Zamarreño galder at redhat.com
Wed Feb 19 02:12:08 EST 2014


On 03 Feb 2014, at 19:01, Dan Berindei <dan.berindei at gmail.com> wrote:

> 
> 
> 
> On Mon, Feb 3, 2014 at 6:28 PM, Radim Vansa <rvansa at redhat.com> wrote:
> >>>> For sync we would want to invoke directly to avoid context switching.
> >>> I think you haven't properly understood what I was talking about: the
> >>> putAsync should not switch context at all in the ideal design. It should
> >>> traverse through the interceptors all the way down (logically, in
> >>> current behaviour), invoke JGroups async API and jump out. Then, as soon
> >>> as the response is received, the thread which delivered it should
> >>> traverse the interceptor stack up (again, logically), and fire the future.
> > A Future doesn't make much sense with an async transport.  The problem
> > is with an async transport you never get back a response so you never
> > know when the actual command is completed and thus a Future is
> > worthless.  The caller wouldn't know if they could rely on the use of
> > the Future or not.
> 
> You're right, there's one important difference between putAsync and put
> with async transport: in the first case you can find out when the
> request is completed while you cannot with the latter. Not requiring the
> ack can be an important optimization. I think that both versions are
> very valid: first mostly for bulk operations = reduction of latency,
> second for modifications that are acceptable to fail without handling that.
> I had the first case in my mind when talking about async operations, and
> there the futures are necessary.
> 
> A couple more differences:
> 1. You can't do commitAsync(), but you can configure the commit to be replicated asynchronously (1PC). Although we did talk about removing that option...
> 2. If you do putAsync(k, v1); putAsync(k, v2), there is no ordering between the two and you might end up with k=v1 in the cache.

If there’s any relationship between both puts for the caller thread, the caller must make sure that the second put is only called after the first has completed. 

If there’s separate threads calling it and it relies on this, it should call replace the second time, i.e. replaceAsync(k, v1, v2) to get the guarantees it wants.

What is really important is that the order in which they are executed in one node/replica is the same order in which they’re executed in all other nodes. This was something that was not maintained when async marshalling was enabled.

> 
> 
> >
> > Also it depends what you are trying to do with async.  Currently async
> > transport is only for sending messages to another node, we never think
> > of when we are the owning node.  In this case the calling thread would
> > have to go down the interceptor stack and acquire any locks if it is
> > the owner, thus causing this "async" to block if you have any
> > contention on the given key.  The use of another thread would allow
> > the calling thread to be able to return immediately no matter what
> > else is occurring.  Also I don't see what is so wrong about having a
> > context switch to run something asynchronously, we shouldn't have a
> > context switch to block the user thread imo, which is very possible
> > with locking.
> 
> This is an important notice! Locking would complicate the design a lot,
> because the thread in "async" mode should do only tryLocks - if this
> fails, further processing should be dispatched to another thread. Not
> sure if this could be implemented at all, because the thread may be
> blocked inside JGroups as well (async API is about receiving the
> response asynchronously, not about sending the message asynchronously).
> 
> I don't say that the context switch is that bad. My concern is that you
> have a very limited amount of requests that can be processed in
> parallel. I consider a "request" something pretty lightweight in concept
> - but one thread per request makes this rather heavyweight stuff.
> 
> We did talk in Farnborough/Palma about removing the current LockManager with a queue-based structure like the one used for ordering total-order transactions. And about removing the implicit stack in the current interceptor stack with an explicit stack, to allow resuming a command mid-execution. But the feeling I got was that neither is going to make it into 7.0.
>  
> 
> >
> >> +1 much cleaner, I love it. Actually wasn't aware the current code
> >> didn't do this :-(
> > This is what the current async transport does, but it does nothing with Futures.
> 
> Nevermind the futures, this is not the important part. It's not about
> async transport neither, it's about async executors.
> (okay, the thread was about dropping async transport, I have hijacked it)
> 
> Radim
> 
> --
> Radim Vansa <rvansa at redhat.com>
> JBoss DataGrid QA
> 
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
> 
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev


--
Galder Zamarreño
galder at redhat.com
twitter.com/galderz

Project Lead, Escalante
http://escalante.io

Engineer, Infinispan
http://infinispan.org




More information about the infinispan-dev mailing list