Search in sources :

Example 6 with TXRegionLockRequestImpl

use of org.apache.geode.internal.cache.TXRegionLockRequestImpl in project geode by apache.

the class TXLockServiceDUnitTest method testTXGrantorMigration.

@Test
public void testTXGrantorMigration() throws Exception {
    // first make sure some other VM is the grantor
    Host.getHost(0).getVM(0).invoke("become lock grantor", () -> {
        TXLockService.createDTLS();
        TXLockService vm0dtls = TXLockService.getDTLS();
        DLockService vm0dlock = ((TXLockServiceImpl) vm0dtls).getInternalDistributedLockService();
        vm0dlock.becomeLockGrantor();
    });
    TXLockService.createDTLS();
    checkDLockRecoverGrantorMessageProcessor();
    /*
     * call TXRecoverGrantorMessageProcessor.process directly to make sure that correct behavior
     * occurs
     */
    // get txLock and hold it
    final List regionLockReqs = new ArrayList();
    regionLockReqs.add(new TXRegionLockRequestImpl("/testTXRecoverGrantorMessageProcessor2", new HashSet(Arrays.asList(new String[] { "KEY-1", "KEY-2", "KEY-3", "KEY-4" }))));
    TXLockService dtls = TXLockService.getDTLS();
    TXLockId txLockId = dtls.txLock(regionLockReqs, Collections.EMPTY_SET);
    final DLockService dlock = ((TXLockServiceImpl) dtls).getInternalDistributedLockService();
    // GEODE-2024: now cause grantor migration while holding the recoveryReadLock.
    // It will lock up in TXRecoverGrantorMessageProcessor until the recoveryReadLock
    // is released. Demonstrate that dtls.release() does not block forever and releases the
    // recoveryReadLock
    // allowing grantor migration to finish
    // create an observer that will block recovery messages from being processed
    MessageObserver observer = new MessageObserver();
    DistributionMessageObserver.setInstance(observer);
    try {
        System.out.println("starting thread to take over being lock grantor from vm0");
        // become the grantor - this will block waiting for a reply to the message blocked by the
        // observer
        Thread thread = new Thread(() -> {
            dlock.becomeLockGrantor();
        });
        thread.setName("TXLockServiceDUnitTest thread2");
        thread.setDaemon(true);
        thread.start();
        await("waiting for recovery to begin").atMost(10, TimeUnit.SECONDS).until(() -> {
            return observer.isPreventingProcessing();
        });
        // spawn a thread that will unblock message processing
        // so that TXLockServiceImpl's "recovering" variable will be set
        System.out.println("starting a thread to unblock recovery in 5 seconds");
        Thread unblockThread = new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException("sleep interrupted");
            }
            System.out.println("releasing block of recovery message processing");
            observer.releasePreventionOfProcessing();
        });
        unblockThread.setName("TXLockServiceDUnitTest unblockThread");
        unblockThread.setDaemon(true);
        unblockThread.start();
        // release txLock - this will block until unblockThread tells the observer
        // that it can process its message. Then it should release the recovery read-lock
        // allowing the grantor to finish recovery
        System.out.println("releasing transaction locks, which should block for a bit");
        dtls.release(txLockId);
        await("waiting for recovery to finish").atMost(10, TimeUnit.SECONDS).until(() -> {
            return !((TXLockServiceImpl) dtls).isRecovering();
        });
    } finally {
        observer.releasePreventionOfProcessing();
        DistributionMessageObserver.setInstance(null);
    }
}
Also used : DistributionMessageObserver(org.apache.geode.distributed.internal.DistributionMessageObserver) ArrayList(java.util.ArrayList) TXRegionLockRequestImpl(org.apache.geode.internal.cache.TXRegionLockRequestImpl) DLockService(org.apache.geode.distributed.internal.locks.DLockService) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest) DLockTest(org.apache.geode.test.junit.categories.DLockTest)

Aggregations

TXRegionLockRequestImpl (org.apache.geode.internal.cache.TXRegionLockRequestImpl)6 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 List (java.util.List)4 DLockTest (org.apache.geode.test.junit.categories.DLockTest)4 DistributedTest (org.apache.geode.test.junit.categories.DistributedTest)4 Test (org.junit.Test)4 Set (java.util.Set)3 CommitConflictException (org.apache.geode.cache.CommitConflictException)2 DLockService (org.apache.geode.distributed.internal.locks.DLockService)2 SerializableRunnable (org.apache.geode.test.dunit.SerializableRunnable)2 DistributionMessageObserver (org.apache.geode.distributed.internal.DistributionMessageObserver)1 DLockRecoverGrantorProcessor (org.apache.geode.distributed.internal.locks.DLockRecoverGrantorProcessor)1 DLockRecoverGrantorMessage (org.apache.geode.distributed.internal.locks.DLockRecoverGrantorProcessor.DLockRecoverGrantorMessage)1 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)1 InternalCache (org.apache.geode.internal.cache.InternalCache)1 TXLockRequest (org.apache.geode.internal.cache.TXLockRequest)1 TXRegionLockRequest (org.apache.geode.internal.cache.locks.TXRegionLockRequest)1