[infinispan-dev] ISPN-293 getAsync impl requires more reengineering

Sanne Grinovero sanne.grinovero at gmail.com
Wed Feb 9 05:14:15 EST 2011


2011/2/9 Galder Zamarreño <galder at redhat.com>:
> Hi,
>
> Re: https://issues.jboss.org/browse/ISPN-293
>
> I have an issue with my implementation that simply wraps the realRemoteGet in DistributionInterceptor around a Callable:
>
> Assume that cache is configured with Distribution(numOwners=1, l1=enabled), no transactions, and we have a cluster of 2 nodes:
>
> - [main-thread] Put k0 in a cache that should own it.
> - [main-thread] Do a getAsync for k0 from a node that does not own it:
> - [async-thread] This leads to a remote get which updates the L1 and updates the context created by the main-thread and putting the updated entry in there (however, this thread does not release the locks)
> - [main-thread] Next up, we put a new key, i.e. k1, in the node that didn't own k0 (the node where we updated the L1 cache):
> - Now this thread has used the same context that the async thread used, so when it comes to releasing locks, it finds two entries in the context, the one locked by the async-thread and one for the main-thread and it fails with java.lang.IllegalMonitorStateException

Hi Galder, please note I'm working on ISPN-919 : my task in this case
is to have the IllegalMonitorStateException ignored/swallowed; my
patch is trivial, my pull request was delayed yesterday just because I
couldn't create a proper test and I'm still figuring out which
scenarios trigger my stacktraces.

I don't think this eases/solves you problem, as I guess you still will
need to do all lock releases in the separate thread, but remember this
behaviour might change pretty soon.

For Hibernate's purpose, I'd expect this asyncGet to share the same
transaction as [main-thread] and release locks / commit at the same
time - I hope that's possible?

Regards,
Sanne


>
> Now, what's happening here is the async-thread is acquiring the lock but not releasing it because the release happens in the DistLockInterceptor/LockingInterceptor, so a different interceptor to where the lock is being acquired. So, in theory, the solution would be for DistLockInterceptor to wrap the invokeNext() and afterCall() for when an async get so that all "remote get", "l1 update", and "release locks", happen in a separate thread. However, for this to work, it will need to figure out whether a remoteGet() will be necessary in the first place, otherwise is useless. Whether the remoteGet should happen is determined by this code in DistributionInterceptor:
>
> if (ctx.isOriginLocal() && !(isMappedToLocalNode = dm.isLocal(key)) && isNotInL1(key)) {
>
> Also, if DistLockInterceptor does this check, we need to make sure DistributionInterceptor does not do it again, otherwise it's a waste. I think this might work although it does require some further reengineering.
>
> I'm gonna try to implement this but wondering whether anyone can see any potential flaws here, or if anyone has any better ideas :)
>
> Cheers,
> --
> Galder Zamarreño
> Sr. Software Engineer
> Infinispan, JBoss Cache
>
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>



More information about the infinispan-dev mailing list