Async Options
shane_dev Jul 21, 2010 12:17 PMWhat the difference is between the various async options in Infinispan? FYI: We are using Infinispan in replicated mode, so that is what I am referencing below.
Here is what I found so far...
Put Async
- CacheDelegate.putAsync
- InterceptorChain.invoke
- PutKeyValueCommand.acceptVisitor
- ReplicationInterceptor.visitPutKeyValueCommand
- ReplicationInterceptor.handleCrudMethod
- RpcManagerImpl.broadcastRpcCommandInFuture
- RpcManagerImpl.invokeRemotelyInFuture (Create Callable, Submit to ExecutorService)
- RETURN
Aysnc Marshalling
- CacheDelegate.put
- InterceptorChain.invoke
- PutKeyValueCommand.acceptVisitor
- ReplicationInterceptor.visitPutKeyValueCommand
- ReplicationInterceptor.handleCrudMethod
- RpcManagerImpl.broadcastRpcCommand
- RpcManagerImpl.invokeRemotely
- JGroupsTransport.invokeRemotely
- CommandAwareRpcDispatcher.invokeRemoteCommands (Create Replication Task, Submit to ExecutorService)
- RETURN
Replication Queue
- CacheDelegate.put
- InterceptorChain.invoke
- PutKeyValueCommand.acceptVisitor
- ReplicationInterceptor.visitPutKeyValueCommand
- ReplicationInterceptor.handleCrudMethod
- RpcManagerImpl.broadcastRpcCommand
- ReplicationQueue.add (Flush via Add or ScheduledExecutorService)
- RETURN
The only practical difference I have seen is that putAsync returns a Future whereas the others do not. However, it looks like the performance difference is neglibile between it and the others.
While putAsync terminates with RpcManagerImpl, async marshalling terminates with CommandAwareRpcDispatcher. However, there seems to be very little going on between the rpc, transport, and dispatcher calls. Also, it doesn't seem to have anything to do with marshalling? The marshalling seems to take place in ReplicationTask.marshallCall via (ReplicationTask.call). Regardless of whether async marshalling is enabled or not, this call doesn't take place until the task is called/executed.
The replication queue seems to be the fastest in our testing. It actually returns sooner than putAsync. This seems to be the best option. Is there any reason to use async marshalling over the replication queue seeing as they are both async?
I noticed that putAsync begins passing along the sync flag with a value of true while the async marshalling path does not. Does this mean that you can use a replication queue with async marshalling? I'm pretty sure you wouldn't want to, but I'm just curious as to if the code would actually let you do that.
Finally, it looks entirely too dangerous to use more than one thread with the putAsync/async marshalling executors. So much so that it is never practical to do so seeing as the ordering may be lost, and in our test was. Is this something that can be looked at in the future? It would be nice to do some sort of locking at the key level so as to ensure ordering of sequential operations on a particular key while be able to process operations for multiple keys in parallel.