Search in sources :

Example 1 with DLockRemoteToken

use of org.apache.geode.distributed.internal.locks.DLockRemoteToken in project geode by apache.

the class DistributedLockServiceDUnitTest method testLockQuery.

@Test
public void testLockQuery() throws Exception {
    final String dlsName = getUniqueName();
    final VM vmGrantor = Host.getHost(0).getVM(0);
    final VM vm1 = Host.getHost(0).getVM(1);
    final VM vm2 = Host.getHost(0).getVM(2);
    final String key1 = "key1";
    // vmGrantor creates grantor
    vmGrantor.invoke(new SerializableRunnable() {

        public void run() {
            LogWriterUtils.getLogWriter().info("[testLockQuery] vmGrantor creates grantor");
            connectDistributedSystem();
            DLockService dls = (DLockService) DistributedLockService.create(dlsName, getSystem());
            assertTrue(dls.lock(key1, -1, -1));
            assertTrue(dls.isLockGrantor());
            dls.unlock(key1);
            dls.freeResources(key1);
        }
    });
    AsyncInvocation whileVM1Locks = null;
    try {
        // vm1 locks key1
        whileVM1Locks = vm1.invokeAsync(new SerializableRunnable() {

            public void run() {
                LogWriterUtils.getLogWriter().info("[testLockQuery] vm1 locks key1");
                connectDistributedSystem();
                DLockService dls = (DLockService) DistributedLockService.create(dlsName, getSystem());
                assertTrue(dls.lock(key1, -1, -1));
                assertFalse(dls.isLockGrantor());
                try {
                    synchronized (testLockQuery_whileVM1Locks) {
                        testLockQuery_whileVM1Locks.set(true);
                        testLockQuery_whileVM1Locks.notifyAll();
                        long maxWait = 10000;
                        StopWatch timer = new StopWatch(true);
                        while (testLockQuery_whileVM1Locks.get()) {
                            // while true
                            long timeLeft = maxWait - timer.elapsedTimeMillis();
                            if (timeLeft > 0) {
                                testLockQuery_whileVM1Locks.wait(timeLeft);
                            } else {
                                fail("Test attempted to wait too long");
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    org.apache.geode.test.dunit.Assert.fail(e.getMessage(), e);
                }
                LogWriterUtils.getLogWriter().info("[testLockQuery] vm1 unlocks key1");
                dls.unlock(key1);
                dls.freeResources(key1);
            }
        });
        // wait for vm1 to set testLockQuery_whileVM1Locks
        // get DistributedMember for vm1
        final DistributedMember vm1Member = (DistributedMember) vm1.invoke(new SerializableCallable() {

            public Object call() throws Exception {
                LogWriterUtils.getLogWriter().info("[testLockQuery] vm1 waits for locking thread");
                synchronized (testLockQuery_whileVM1Locks) {
                    long maxWait = 10000;
                    StopWatch timer = new StopWatch(true);
                    while (!testLockQuery_whileVM1Locks.get()) {
                        // while false
                        long timeLeft = maxWait - timer.elapsedTimeMillis();
                        if (timeLeft > 0) {
                            testLockQuery_whileVM1Locks.wait(timeLeft);
                        } else {
                            fail("Test attempted to wait too long");
                        }
                    }
                }
                return getSystem().getDistributedMember();
            }
        });
        assertNotNull(vm1Member);
        // vmGrantor tests positive local dlock query
        vmGrantor.invoke(new SerializableRunnable() {

            public void run() {
                LogWriterUtils.getLogWriter().info("[testLockQuery] vmGrantor tests local query");
                DLockService dls = (DLockService) DistributedLockService.getServiceNamed(dlsName);
                DLockRemoteToken result = dls.queryLock(key1);
                assertNotNull(result);
                assertEquals(key1, result.getName());
                assertTrue(result.getLeaseId() != -1);
                assertEquals(Long.MAX_VALUE, result.getLeaseExpireTime());
                RemoteThread lesseeThread = result.getLesseeThread();
                assertNotNull(lesseeThread);
                assertEquals(vm1Member, lesseeThread.getDistributedMember());
                assertEquals(vm1Member, result.getLessee());
            // nothing to test for on threadId unless we serialize info from vm1
            }
        });
        // vm2 tests positive remote dlock query
        vm2.invoke(new SerializableRunnable() {

            public void run() {
                LogWriterUtils.getLogWriter().info("[testLockQuery] vm2 tests remote query");
                connectDistributedSystem();
                DLockService dls = (DLockService) DistributedLockService.create(dlsName, getSystem());
                DLockRemoteToken result = dls.queryLock(key1);
                assertNotNull(result);
                assertEquals(key1, result.getName());
                assertTrue(result.getLeaseId() != -1);
                assertEquals(Long.MAX_VALUE, result.getLeaseExpireTime());
                RemoteThread lesseeThread = result.getLesseeThread();
                assertNotNull(lesseeThread);
                assertEquals(vm1Member, lesseeThread.getDistributedMember());
                assertEquals(vm1Member, result.getLessee());
            // nothing to test for on threadId unless we serialize info from vm1
            }
        });
    } finally {
        // guarantee that testLockQuery_whileVM1Locks is notfied!
        // vm1 sets and notifies testLockQuery_whileVM1Locks to release lock
        vm1.invoke(new SerializableRunnable() {

            public void run() {
                LogWriterUtils.getLogWriter().info("[testLockQuery] vm1 notifies/releases key1");
                synchronized (testLockQuery_whileVM1Locks) {
                    testLockQuery_whileVM1Locks.set(false);
                    testLockQuery_whileVM1Locks.notifyAll();
                }
            }
        });
        ThreadUtils.join(whileVM1Locks, 10 * 1000);
        if (whileVM1Locks.exceptionOccurred()) {
            org.apache.geode.test.dunit.Assert.fail("Test failed", whileVM1Locks.getException());
        }
    }
    // vmGrantor tests negative local dlock query
    vmGrantor.invoke(new SerializableRunnable() {

        public void run() {
            LogWriterUtils.getLogWriter().info("[testLockQuery] vmGrantor tests negative query");
            DLockService dls = (DLockService) DistributedLockService.getServiceNamed(dlsName);
            DLockRemoteToken result = dls.queryLock(key1);
            assertNotNull(result);
            assertEquals(key1, result.getName());
            assertEquals(-1, result.getLeaseId());
            assertEquals(0, result.getLeaseExpireTime());
            assertNull(result.getLesseeThread());
            assertNull(result.getLessee());
        }
    });
    // vm2 tests negative remote dlock query
    vm2.invoke(new SerializableRunnable() {

        public void run() {
            LogWriterUtils.getLogWriter().info("[testLockQuery] vm2 tests negative query");
            DLockService dls = (DLockService) DistributedLockService.getServiceNamed(dlsName);
            DLockRemoteToken result = dls.queryLock(key1);
            assertNotNull(result);
            assertEquals(key1, result.getName());
            assertEquals(-1, result.getLeaseId());
            assertEquals(0, result.getLeaseExpireTime());
            assertNull(result.getLesseeThread());
            assertNull(result.getLessee());
        }
    });
}
Also used : RemoteThread(org.apache.geode.distributed.internal.locks.RemoteThread) VM(org.apache.geode.test.dunit.VM) SerializableCallable(org.apache.geode.test.dunit.SerializableCallable) SerializableRunnable(org.apache.geode.test.dunit.SerializableRunnable) DLockService(org.apache.geode.distributed.internal.locks.DLockService) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) AsyncInvocation(org.apache.geode.test.dunit.AsyncInvocation) DLockRemoteToken(org.apache.geode.distributed.internal.locks.DLockRemoteToken) StopWatch(org.apache.geode.internal.util.StopWatch) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest) DLockTest(org.apache.geode.test.junit.categories.DLockTest)

Example 2 with DLockRemoteToken

use of org.apache.geode.distributed.internal.locks.DLockRemoteToken in project geode by apache.

the class TXRecoverGrantorMessageProcessor method processDLockRecoverGrantorMessage.

protected void processDLockRecoverGrantorMessage(final DM dm, final DLockRecoverGrantorProcessor.DLockRecoverGrantorMessage msg) {
    ReplyException replyException = null;
    int replyCode = DLockRecoverGrantorProcessor.DLockRecoverGrantorReplyMessage.OK;
    DLockRemoteToken[] heldLocks = new DLockRemoteToken[0];
    if (logger.isDebugEnabled()) {
        logger.debug("[TXRecoverGrantorMessageProcessor.process]");
    }
    boolean gotRecoveryLock = false;
    TXLockServiceImpl dtls = null;
    try {
        Assert.assertTrue(msg.getServiceName().startsWith(DLockService.DTLS), "TXRecoverGrantorMessageProcessor cannot handle service " + msg.getServiceName());
        // get the service from the name
        DLockService svc = DLockService.getInternalServiceNamed(msg.getServiceName());
        if (svc != null) {
            dtls = (TXLockServiceImpl) TXLockService.getDTLS();
            if (dtls != null) {
                // use TXLockServiceImpl recoveryLock to delay reply...
                dtls.acquireRecoveryWriteLock();
                gotRecoveryLock = true;
                // Wait for all the received transactions to finish processing
                TXCommitMessage.getTracker().waitForAllToProcess();
            }
        }
    } catch (InterruptedException t) {
        Thread.currentThread().interrupt();
        logger.warn(LocalizedMessage.create(LocalizedStrings.TXRecoverGrantorMessageProcessor_TXRECOVERGRANTORMESSAGEPROCESSORPROCESS_THROWABLE), t);
        replyException = new ReplyException(t);
    } catch (RuntimeException t) {
        logger.warn(LocalizedMessage.create(LocalizedStrings.TXRecoverGrantorMessageProcessor_TXRECOVERGRANTORMESSAGEPROCESSORPROCESS_THROWABLE), t);
        if (replyException == null) {
            replyException = new ReplyException(t);
        } else {
            logger.warn(LocalizedMessage.create(LocalizedStrings.TXRecoverGrantorMessageProcessor_MORE_THAN_ONE_EXCEPTION_THROWN_IN__0, this), t);
        }
    } finally // catch (VirtualMachineError err) {
    // SystemFailure.initiateFailure(err);
    // // If this ever returns, rethrow the error. We're poisoned
    // // now, so don't let this thread continue.
    // throw err;
    // }
    // catch (Throwable t) {
    // // Whenever you catch Error or Throwable, you must also
    // // catch VirtualMachineError (see above). However, there is
    // // _still_ a possibility that you are dealing with a cascading
    // // error condition, so you also need to check to see if the JVM
    // // is still usable:
    // SystemFailure.checkFailure();
    // if (replyException == null) {
    // replyException = new ReplyException(t);
    // }
    // }
    {
        if (gotRecoveryLock && dtls != null) {
            dtls.releaseRecoveryWriteLock();
        }
        DLockRecoverGrantorProcessor.DLockRecoverGrantorReplyMessage replyMsg = new DLockRecoverGrantorProcessor.DLockRecoverGrantorReplyMessage();
        replyMsg.setReplyCode(replyCode);
        replyMsg.setHeldLocks(heldLocks);
        replyMsg.setProcessorId(msg.getProcessorId());
        replyMsg.setRecipient(msg.getSender());
        replyMsg.setException(replyException);
        if (msg.getSender().equals(dm.getId())) {
            // process in-line in this VM
            if (logger.isDebugEnabled()) {
                logger.debug("[TXRecoverGrantorMessageProcessor.process] locally process reply");
            }
            replyMsg.setSender(dm.getId());
            replyMsg.dmProcess((DistributionManager) dm);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("[TXRecoverGrantorMessageProcessor.process] send reply");
            }
            dm.putOutgoing(replyMsg);
        }
    }
}
Also used : DLockRecoverGrantorProcessor(org.apache.geode.distributed.internal.locks.DLockRecoverGrantorProcessor) DLockService(org.apache.geode.distributed.internal.locks.DLockService) ReplyException(org.apache.geode.distributed.internal.ReplyException) DLockRemoteToken(org.apache.geode.distributed.internal.locks.DLockRemoteToken)

Aggregations

DLockRemoteToken (org.apache.geode.distributed.internal.locks.DLockRemoteToken)2 DLockService (org.apache.geode.distributed.internal.locks.DLockService)2 ReplyException (org.apache.geode.distributed.internal.ReplyException)1 DLockRecoverGrantorProcessor (org.apache.geode.distributed.internal.locks.DLockRecoverGrantorProcessor)1 RemoteThread (org.apache.geode.distributed.internal.locks.RemoteThread)1 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)1 StopWatch (org.apache.geode.internal.util.StopWatch)1 AsyncInvocation (org.apache.geode.test.dunit.AsyncInvocation)1 SerializableCallable (org.apache.geode.test.dunit.SerializableCallable)1 SerializableRunnable (org.apache.geode.test.dunit.SerializableRunnable)1 VM (org.apache.geode.test.dunit.VM)1 DLockTest (org.apache.geode.test.junit.categories.DLockTest)1 DistributedTest (org.apache.geode.test.junit.categories.DistributedTest)1 Test (org.junit.Test)1