You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2010/11/11 16:22:11 UTC

svn commit: r1033964 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/lock/ test/java/org/apache/jackrabbit/core/lock/

Author: thomasm
Date: Thu Nov 11 15:22:11 2010
New Revision: 1033964

URL: http://svn.apache.org/viewvc?rev=1033964&view=rev
Log:
JCR-2809 Lock expires almost immediately

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/LockTimeoutTest.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java?rev=1033964&r1=1033963&r2=1033964&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java Thu Nov 11 15:22:11 2010
@@ -139,8 +139,9 @@ class LockImpl implements javax.jcr.lock
             return Long.MAX_VALUE;
         }
 
-        long now = (System.currentTimeMillis() + 999) / 1000; // round up
-        return Math.max(timeout - now, 1); // must always be positive
+        long remainingSeconds = (timeout - System.currentTimeMillis()) / 1000;
+
+        return Math.max(remainingSeconds, 1); // must always be positive
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java?rev=1033964&r1=1033963&r2=1033964&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockInfo.java Thu Nov 11 15:22:11 2010
@@ -63,7 +63,7 @@ public abstract class LockInfo {
     private final long timeoutHint;
 
     /**
-     * Time (in seconds since epoch) when this lock will timeout. Set to
+     * Time (in milliseconds since the epoch) when this lock will timeout. Set to
      * {@link Long#MAX_VALUE} if this lock will not timeout.
      */
     private long timeoutTime;
@@ -128,7 +128,7 @@ public abstract class LockInfo {
 
     /**
      * Return the lock owner.
-     * 
+     *
      * @return lock owner
      */
     public String getLockOwner() {
@@ -137,7 +137,7 @@ public abstract class LockInfo {
 
     /**
      * Return a flag indicating whether the lock is deep.
-     * 
+     *
      * @return <code>true</code> if the lock is deep;
      *         <code>false</code> otherwise
      */
@@ -146,7 +146,7 @@ public abstract class LockInfo {
     }
 
     /**
-     * Return a flag indicating whether the session given is lock holder. 
+     * Return a flag indicating whether the session given is lock holder.
      *
      * @param session session to compare with
      */
@@ -219,9 +219,9 @@ public abstract class LockInfo {
     }
 
     /**
-     * Returns the time when this lock will expire. 
+     * Returns the time when this lock will expire.
      *
-     * @return timeout time in seconds after epoch
+     * @return timeout time in milliseconds since the epoch
      */
     public long getTimeoutTime() {
         return timeoutTime;
@@ -229,7 +229,7 @@ public abstract class LockInfo {
 
     public boolean isExpired() {
         return timeoutTime != Long.MAX_VALUE
-            && timeoutTime * 1000 > System.currentTimeMillis();
+            && System.currentTimeMillis() > timeoutTime;
     }
 
     /**
@@ -239,8 +239,8 @@ public abstract class LockInfo {
      */
     public void updateTimeoutTime() {
         if (timeoutHint > 0 && timeoutHint <= MAXIMUM_TIMEOUT) {
-            long now = (System.currentTimeMillis() + 999) / 1000; // round up
-            this.timeoutTime = now + timeoutHint;
+            long now = System.currentTimeMillis();
+            this.timeoutTime = now + timeoutHint * 1000;
         } else {
             this.timeoutTime = Long.MAX_VALUE;
         }
@@ -287,9 +287,9 @@ public abstract class LockInfo {
         }
         buffer.append("holder:");
         if (lockHolder != null) {
-            buffer.append(lockHolder.getUserID());
+            buffer.append(lockHolder.getUserID()).append(' ');
         } else {
-            buffer.append("none");
+            buffer.append("none ");
         }
         buffer.append("owner:").append(lockOwner);
         buffer.append(')');

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java?rev=1033964&r1=1033963&r2=1033964&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java Thu Nov 11 15:22:11 2010
@@ -149,7 +149,7 @@ class XAEnvironment {
 
         // create a new lock info for this node
         String lockOwner = (ownerInfo != null) ? ownerInfo : node.getSession().getUserID();
-        info = new XALockInfo(node, isSessionScoped, isDeep, lockOwner);
+        info = new XALockInfo(node, isSessionScoped, isDeep, timeoutHint, lockOwner);
         SessionImpl session = (SessionImpl) node.getSession();
         info.setLockHolder(session);
         info.setLive(true);
@@ -444,8 +444,8 @@ class XAEnvironment {
          */
         public XALockInfo(
                 NodeImpl node,
-                boolean sessionScoped, boolean deep, String lockOwner) {
-            super(node.getNodeId(), sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+                boolean sessionScoped, boolean deep, long timeoutHint, String lockOwner) {
+            super(node.getNodeId(), sessionScoped, deep, lockOwner, timeoutHint);
             this.node = node;
         }
 
@@ -481,7 +481,9 @@ class XAEnvironment {
             } else {
                 LockInfo internalLock = lockMgr.internalLock(
                         node, isDeep(), isSessionScoped(),
-                        getTimeoutTime(), getLockOwner());
+                        getTimeoutHint(),
+//                        getTimeoutTime(),
+                        getLockOwner());
                 LockInfo xaEnvLock = getLockInfo(node);
                 // Check if the lockToken has been removed in the transaction ...
                 if (xaEnvLock != null && xaEnvLock.getLockHolder() == null) {

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/LockTimeoutTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/LockTimeoutTest.java?rev=1033964&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/LockTimeoutTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/LockTimeoutTest.java Thu Nov 11 15:22:11 2010
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.lock;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.lock.Lock;
+import javax.transaction.UserTransaction;
+import org.apache.jackrabbit.core.UserTransactionImpl;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * Test lock timeout expiration.
+ */
+public class LockTimeoutTest extends AbstractJCRTest {
+
+    public void testExpired() throws Exception {
+        testExpired(false);
+        testExpired(true);
+    }
+
+    private void testExpired(boolean xa) throws Exception {
+        Session s = testRootNode.getSession();
+        Node n = testRootNode.addNode(nodeName1);
+        n.addMixin(mixLockable);
+        s.save();
+
+        UserTransaction utx = null;
+        if (xa) {
+            utx = new UserTransactionImpl(s);
+            utx.begin();
+        }
+
+        javax.jcr.lock.LockManager lm = s.getWorkspace().getLockManager();
+
+        boolean isDeep;
+        boolean isSessionScoped;
+        long timeoutHint;
+        String ownerInfo;
+
+        isDeep = false;
+        isSessionScoped = false;
+        timeoutHint = 1;
+        ownerInfo = "";
+        Session s2 = getHelper().getSuperuserSession();
+
+        Lock l = lm.lock(n.getPath(), isDeep, isSessionScoped, timeoutHint, ownerInfo);
+        // this works only for timeout = 1,
+        // as getSecondsRemaining always returns a positive value
+        assertEquals(timeoutHint, l.getSecondsRemaining());
+        assertTrue(l.isLive());
+
+        if (xa) {
+            utx.commit();
+        }
+
+        long start = System.currentTimeMillis();
+        while (true) {
+            Thread.sleep(100);
+            long now = System.currentTimeMillis();
+            boolean success;
+            try {
+                s2.getNode(n.getPath()).setProperty("x", 1);
+                s2.save();
+                success = true;
+            } catch (Exception e) {
+                success = false;
+            }
+            long t = now - start;
+            if (t > timeoutHint + 3000) {
+                assertTrue(success);
+                break;
+            } else if (t < timeoutHint) {
+                assertFalse(success);
+            }
+        }
+        n.remove();
+        s.save();
+    }
+
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/TestAll.java?rev=1033964&r1=1033963&r2=1033964&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/lock/TestAll.java Thu Nov 11 15:22:11 2010
@@ -35,7 +35,10 @@ public class TestAll extends TestCase {
     public static Test suite() {
         TestSuite suite = new TestSuite("org.apache.jackrabbit.core.lock tests");
 
+        suite.addTestSuite(ConcurrentLockingTest.class);
+        suite.addTestSuite(ConcurrentLockingWithTransactionsTest.class);
         suite.addTestSuite(ExtendedLockingTest.class);
+        suite.addTestSuite(LockTimeoutTest.class);
 
         return suite;
     }