]
Daniele Pirola commented on ISPN-4778:
--------------------------------------
Is there a chance to see this fix inside 6.0.2.Final ? Jboss wildfly 8.2 ships with
infinispan 6.0.2.Final, I try to upgrade to 7.2.0.CR1 with no luck.
PessimisticLockingInterceptor throws when handling remote clear
command
-----------------------------------------------------------------------
Key: ISPN-4778
URL:
https://issues.jboss.org/browse/ISPN-4778
Project: Infinispan
Issue Type: Bug
Affects Versions: 6.0.2.Final
Environment: JBoss WildFly 8.1.0.FINAL
Reporter: Arjan t
Assignee: Pedro Ruivo
Labels: remote
Using InfiniSpan as it's shipped with Jboss WildFly 8.1.0.Final as distributed cache
for Hibernate, it appears that the ClearCommand does not work in a cluster when
*pessimistic locking* is used. Pessimistic locking seems to be the default in WildFly,
even when theoretically it shouldn't be.
This will result in the following exception:
{noformat}
java.lang.ClassCastException: org.infinispan.context.impl.NonTxInvocationContext cannot
be cast to org.infinispan.context.impl.TxInvocationContext
at
org.infinispan.interceptors.locking.PessimisticLockingInterceptor.visitClearCommand(PessimisticLockingInterceptor.java:194)
at org.infinispan.commands.write.ClearCommand.acceptVisitor(ClearCommand.java:38)
at
org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:98)
at
org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:112)
at org.infinispan.commands.AbstractVisitor.visitClearCommand(AbstractVisitor.java:47)
at org.infinispan.commands.write.ClearCommand.acceptVisitor(ClearCommand.java:38)
at
org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:98)
at
org.infinispan.interceptors.TxInterceptor.enlistWriteAndInvokeNext(TxInterceptor.java:255)
at org.infinispan.interceptors.TxInterceptor.visitClearCommand(TxInterceptor.java:206)
at org.infinispan.commands.write.ClearCommand.acceptVisitor(ClearCommand.java:38)
at
org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:98)
at
org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:112)
at org.infinispan.commands.AbstractVisitor.visitClearCommand(AbstractVisitor.java:47)
at org.infinispan.commands.write.ClearCommand.acceptVisitor(ClearCommand.java:38)
at
org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:98)
at
org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:110)
at
org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:73)
at org.infinispan.commands.AbstractVisitor.visitClearCommand(AbstractVisitor.java:47)
at org.infinispan.commands.write.ClearCommand.acceptVisitor(ClearCommand.java:38)
at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:333)
at
org.infinispan.commands.remote.BaseRpcInvokingCommand.processVisitableCommand(BaseRpcInvokingCommand.java:39)
at org.infinispan.commands.remote.SingleRpcCommand.perform(SingleRpcCommand.java:48)
at
org.infinispan.remoting.InboundInvocationHandlerImpl.handleInternal(InboundInvocationHandlerImpl.java:95)
at
org.infinispan.remoting.InboundInvocationHandlerImpl.access$000(InboundInvocationHandlerImpl.java:50)
at
org.infinispan.remoting.InboundInvocationHandlerImpl$2.run(InboundInvocationHandlerImpl.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
{noformat}
The incoming command looks as follows:
{noformat}
CacheRpcCommand cmd:
command:
ClearCommand{flags=null}
icf:
org.infinispan.context.TransactionalInvocationContextFactory@3ef1861e
Interceptor chain:
>> org.infinispan.interceptors.InvocationContextInterceptor -- checks if
stopping, otherwise continues
>> org.infinispan.interceptors.CacheMgmtInterceptor -- does nothing
>> org.infinispan.interceptors.TxInterceptor -- checks
"shouldEnlist", if false does nothing
>> org.infinispan.interceptors.NotificationInterceptor -- does nothing
>> org.infinispan.interceptors.locking.PessimisticLockingInterceptor -- Throws
exception if something in cache
>> org.infinispan.interceptors.EntryWrappingInterceptor
>> org.infinispan.interceptors.InvalidationInterceptor
>> org.infinispan.interceptors.CallInterceptor
{noformat}
The problem seems to be that
{{org.infinispan.commands.remote.BaseRpcInvokingCommand.processVisitableCommand}} always
creates a {{NonTxInvocationContext}}. As per the following line of code:
{code}
final InvocationContext ctx = icf.createRemoteInvocationContextForCommand(vc,
getOrigin());
{code}
When handling the ClearCommand, the PessimisticLockInterceptor always casts this to a
{{TxInvocationContext}} whenever {{dataContainer}} is not empty, e.g. when there is cached
data on the node where the clear command arrives. This happens in the following code:
{code}
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws
Throwable {
try {
boolean skipLocking = hasSkipLocking(command);
long lockTimeout = getLockAcquisitionTimeout(command, skipLocking);
for (InternalCacheEntry entry : dataContainer.entrySet())
lockAndRegisterBackupLock((TxInvocationContext) ctx, entry.getKey(),
lockTimeout, skipLocking);
return invokeNextInterceptor(ctx, command);
} catch (Throwable te) {
releaseLocksOnFailureBeforePrepare(ctx);
throw te;
}
}
{code}
So seemingly this can't ever work.
Either the {{PessimisticLockingInterceptor}} can't be in a the interceptor chain when
handling commands from a remote destination, or something has to be done about about the
{{InvocationContext}} when handling remote commands?