geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jgenen...@apache.org
Subject svn commit: r503896 - in /geronimo/sandbox/gcache: client/src/main/java/org/apache/geronimo/gcache/transports/tcp/ common/src/main/java/org/apache/geronimo/gcache/command/ common/src/main/java/org/apache/geronimo/gcache/lock/ common/src/main/java/org/a...
Date Mon, 05 Feb 2007 22:11:00 GMT
Author: jgenender
Date: Mon Feb  5 14:10:58 2007
New Revision: 503896

URL: http://svn.apache.org/viewvc?view=rev&rev=503896
Log:
Locking

Added:
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/GetSessionCommand.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/LockCommand.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/ReleaseLockCommand.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/Lock.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockManager.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockTask.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/NotCurrentOwnerException.java
    geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/
    geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockClient.java
    geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTest.java
    geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTimeoutTest.java
Modified:
    geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientCommandVisitor.java
    geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientSocketTransportService.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/CommandTypes.java
    geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/transports/CommandVisitor.java
    geronimo/sandbox/gcache/server/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPCommandVisitor.java

Modified: geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientCommandVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientCommandVisitor.java?view=diff&rev=503896&r1=503895&r2=503896
==============================================================================
--- geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientCommandVisitor.java
(original)
+++ geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientCommandVisitor.java
Mon Feb  5 14:10:58 2007
@@ -31,9 +31,12 @@
 import org.apache.geronimo.gcache.command.BulkSendCommand;
 import org.apache.geronimo.gcache.command.ClearCacheCommand;
 import org.apache.geronimo.gcache.command.GetCacheCommand;
+import org.apache.geronimo.gcache.command.GetSessionCommand;
+import org.apache.geronimo.gcache.command.LockCommand;
 import org.apache.geronimo.gcache.command.MessageAckCommand;
 import org.apache.geronimo.gcache.command.PutEntryCommand;
 import org.apache.geronimo.gcache.command.PutSessionCommand;
+import org.apache.geronimo.gcache.command.ReleaseLockCommand;
 import org.apache.geronimo.gcache.command.RemoveEntryCommand;
 import org.apache.geronimo.gcache.command.RemoveSessionCommand;
 import org.apache.mina.common.IoSession;
@@ -89,6 +92,13 @@
     public void processMessageAck(MessageAckCommand command) {
         // This should never get called as the filters will handle it
     }
+    
+    public void processGetSession(GetSessionCommand command) {
+        Cache cache = infoHolder.getCache(command.getCacheName(), true);
+        Object key = cache.get(command.getSessionId());
+        Element element = cache.get(key);
+        
+    }
 
     @SuppressWarnings("unchecked")
     public void processGetCache(GetCacheCommand command) {
@@ -206,6 +216,14 @@
         }
 
         sendAck(command);
+    }
+
+    public void processLockSession(LockCommand command) {
+        // Shouldn't be processed on client
+    }
+
+    public void processReleaseLockSession(ReleaseLockCommand command) {
+        // Shouldn't be processed on client
     }
     
  

Modified: geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientSocketTransportService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientSocketTransportService.java?view=diff&rev=503896&r1=503895&r2=503896
==============================================================================
--- geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientSocketTransportService.java
(original)
+++ geronimo/sandbox/gcache/client/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPClientSocketTransportService.java
Mon Feb  5 14:10:58 2007
@@ -32,13 +32,12 @@
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoHandler;
 import org.apache.mina.common.IoSession;
+import org.apache.mina.common.WriteFuture;
 import org.apache.mina.filter.LoggingFilter;
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.transport.socket.nio.SocketConnector;
 import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
 
-import com.apple.crypto.provider.CryptoGlobals;
-
 public class TCPClientSocketTransportService extends TCPTransportService implements ClientTransport{
 
     private static Log log = LogFactory.getLog(TCPClientSocketTransportService.class);
@@ -169,10 +168,14 @@
     
     public void send(BaseCommand command){
         
-        sess.write(command);
+        WriteFuture future = sess.write(command);
         
         //Request ack if setup to do so
         command.setAttachment(sess);
         ((TCPClientCommandVisitor)info.getCommandVisitor()).requestAck(command);
+        
+        //Wait for it to be written
+        future.join();
+        
     }
 }

Modified: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/CommandTypes.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/CommandTypes.java?view=diff&rev=503896&r1=503895&r2=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/CommandTypes.java
(original)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/CommandTypes.java
Mon Feb  5 14:10:58 2007
@@ -9,10 +9,13 @@
     public static final byte CLEARCACHE_COMMAND = 6;
     public static final byte MESSAGE_ACK_COMMAND = 7;
     public static final byte BULK_SEND_COMMAND = 8;
-    public static final byte REMOVE_SESSION_COMMAND = 9;
-    public static final byte PUT_SESSION_COMMAND = 10;
-    public static final byte GET_CACHE_COMMAND = 11;
-    public static final byte DISCOVERY_COMMAND = 12;
+    public static final byte GET_SESSION_COMMAND = 9;
+    public static final byte REMOVE_SESSION_COMMAND = 10;
+    public static final byte PUT_SESSION_COMMAND = 11;
+    public static final byte GET_CACHE_COMMAND = 12;
+    public static final byte DISCOVERY_COMMAND = 13;
+    public static final byte LOCK_COMMAND = 14;
+    public static final byte RELEASELOCK_COMMAND = 15;
 
     public static Command createCommand(int identifier) {
         Command command = null;
@@ -41,6 +44,9 @@
             case(BULK_SEND_COMMAND):
                 command = new BulkSendCommand();
                 break;
+            case(GET_SESSION_COMMAND):
+                command = new GetSessionCommand();
+                break;
             case(REMOVE_SESSION_COMMAND):
                 command = new RemoveSessionCommand();
                 break;
@@ -52,6 +58,12 @@
                 break;
             case(DISCOVERY_COMMAND):
                 command = new DiscoveryCommand();
+                break;
+            case (LOCK_COMMAND):
+                command = new LockCommand();
+                break;
+            case (RELEASELOCK_COMMAND):
+                command = new LockCommand();
                 break;
         }
         return command;

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/GetSessionCommand.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/GetSessionCommand.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/GetSessionCommand.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/GetSessionCommand.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,29 @@
+/*
+ * 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.geronimo.gcache.command;
+
+import java.io.IOException;
+
+public class GetSessionCommand extends CacheBaseCommand {
+    
+    public byte getCommandType() throws IOException {
+        return CommandTypes.GET_SESSION_COMMAND;
+    }
+
+}

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/LockCommand.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/LockCommand.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/LockCommand.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/LockCommand.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,35 @@
+/*
+ * 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.geronimo.gcache.command;
+
+import java.io.IOException;
+
+import org.apache.geronimo.gcache.transports.CommandVisitor;
+
+public class LockCommand extends CacheBaseCommand {
+    
+    public byte getCommandType() throws IOException {
+        return CommandTypes.LOCK_COMMAND;
+    }
+    
+    public void execute(CommandVisitor visitor) throws IOException {
+        visitor.processLockSession(this);
+    }
+
+}

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/ReleaseLockCommand.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/ReleaseLockCommand.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/ReleaseLockCommand.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/command/ReleaseLockCommand.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,34 @@
+/*
+ * 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.geronimo.gcache.command;
+
+import java.io.IOException;
+
+import org.apache.geronimo.gcache.transports.CommandVisitor;
+
+public class ReleaseLockCommand extends CacheBaseCommand {
+    public byte getCommandType() throws IOException {
+        return CommandTypes.RELEASELOCK_COMMAND;
+    }
+    
+    public void execute(CommandVisitor visitor) throws IOException {
+        visitor.processReleaseLockSession(this);
+    }
+
+}

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/Lock.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/Lock.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/Lock.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/Lock.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,109 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Lock {
+    private static Log log = LogFactory.getLog(Lock.class);
+    
+    private Semaphore sem = new Semaphore(1, true);
+    private Set<String> lockRequestors = Collections.synchronizedSet(new HashSet<String>());
+
+    private String currentOwner;
+
+    public Lock() {
+    }
+    
+    public boolean hasLock(String owner){
+        synchronized (this) {
+            if (currentOwner == null)
+                return false;
+            return owner.equals(currentOwner);
+        }
+    }
+
+    public String getCurrentOwner() {
+        synchronized (this) {
+            return currentOwner;
+        }
+    }
+
+    public boolean hasQueuedLocks() {
+        return lockRequestors.size() > 0;
+    }
+    
+    public void requestLock(String requestingOwner){
+        lockRequestors.add(requestingOwner);
+    }
+
+    public void acquire(String requestingOwner) throws InterruptedException {
+        // See if the owner already has the lock, and if so, just return
+        synchronized (this) {
+            if (currentOwner != null && requestingOwner.equals(currentOwner))
+                return;
+        }
+
+        // Try to acquire the lock
+        if (log.isDebugEnabled()){
+            log.debug("Attempting to acquire lock on semaphore by " + requestingOwner);
+        }
+        sem.acquire();
+
+        // Set the owner since 
+        synchronized (this) {
+            currentOwner = requestingOwner;
+        }
+    }
+
+    /**
+     * Releases the lock
+     * 
+     * @param requestingOwner
+     * @throws NotCurrentOwnerException
+     */
+    public void release(String requestingOwner) throws NotCurrentOwnerException {
+        // This is method is synchronized since this code must be atomic
+        // So it does not interfere with code in mid stream for an acquire
+        synchronized (this) {
+
+            // Make sure the requester is the owner, or throw an error
+            if (currentOwner == null || !requestingOwner.equals(currentOwner)){
+                throw new NotCurrentOwnerException();
+            }
+            
+            //Remove from the request list
+            lockRequestors.remove(currentOwner);
+            
+            // Clear the currentOwner
+            currentOwner = null;
+            sem.release();
+            
+            if (log.isDebugEnabled()){
+                log.debug("Released lock for " + requestingOwner);
+            }
+        }
+    }
+}

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockManager.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockManager.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockManager.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockManager.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,147 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executors;
+import edu.emory.mathcs.backport.java.util.concurrent.ScheduledFuture;
+import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
+import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
+
+public class LockManager {
+    private static Log log = LogFactory.getLog(LockManager.class);
+
+    public final static int DEFAULT_THREAD_POOL_SIZE = 10;
+
+    public final static int DEFAULT_LOCK_TIMEOUT = 10000; // 10 seconds
+
+    private ConcurrentHashMap<String, LockHandle> lockMap = new ConcurrentHashMap<String,
LockHandle>();
+
+    private final ScheduledThreadPoolExecutor scheduler;
+
+    private int lockTimeout;
+
+    public LockManager() {
+        this(DEFAULT_THREAD_POOL_SIZE, DEFAULT_LOCK_TIMEOUT);
+    }
+
+    public LockManager(int threadPoolSize, int lockTimeout) {
+        this.lockTimeout = lockTimeout;
+        scheduler = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(threadPoolSize);
+        scheduler.scheduleWithFixedDelay(new SchedulePurger(), lockTimeout, lockTimeout,
TimeUnit.MILLISECONDS);
+    }
+
+    public boolean hasLock(String cacheName, String sessionId, String requestingOwner) {
+        String lockId = cacheName + sessionId;
+        synchronized (this) {
+            LockHandle lockHandle = lockMap.get(lockId);
+            if (lockHandle == null)
+                return false;
+            return lockHandle.getLock().hasLock(requestingOwner);
+        }
+    }
+
+    public void acquire(String cacheName, String sessionId, String requestingOwner) throws
InterruptedException {
+        String lockId = cacheName + sessionId;
+        if (log.isDebugEnabled()) {
+            log.debug("Lock acquire requested by " + requestingOwner + " for lockid = " +
lockId);
+        }
+        LockHandle lockHandle = null;
+        synchronized (this) {
+            lockHandle = lockMap.get(lockId);
+            if (lockHandle == null)
+                lockHandle = new LockHandle(new Lock());
+            lockMap.put(lockId, lockHandle);
+            lockHandle.getLock().requestLock(requestingOwner);
+        }
+        lockHandle.getLock().acquire(requestingOwner);
+
+        // Schedule the lock timer
+        lockHandle.schedule(new LockTask(lockId, requestingOwner, this), lockTimeout);
+        if (log.isDebugEnabled()) {
+            log.debug("Lock awarded to " + requestingOwner + " for lockid = " + lockId);
+        }
+    }
+
+    public void release(String cacheName, String sessionId, String requestingOwner) throws
NotCurrentOwnerException {
+        String lockId = cacheName + sessionId;
+        release(lockId, requestingOwner);
+    }
+
+    protected void release(String lockId, String requestingOwner) throws NotCurrentOwnerException
{
+        synchronized (this) {
+            LockHandle lockHandle = lockMap.get(lockId);
+            lockHandle.getLock().release(requestingOwner);
+            lockHandle.unschedule();
+            if (!lockHandle.getLock().hasQueuedLocks()) {
+                lockMap.remove(requestingOwner);
+            }
+        }
+    }
+
+    public void destroy() {
+        scheduler.shutdownNow();
+    }
+
+    class LockHandle {
+        private ScheduledFuture future;
+
+        private Lock lock;
+
+        public LockHandle(Lock lock) {
+            this.lock = lock;
+        }
+
+        public Lock getLock() {
+            return lock;
+        }
+
+        public void schedule(Runnable task, long delay) {
+            future = scheduler.schedule(task, delay, TimeUnit.MILLISECONDS);
+        }
+
+        public void unschedule() {
+            synchronized (lock) {
+                if (future != null) {
+                    // Cancel the task if it hasn't run
+                    future.cancel(false);
+                    // Remove the task
+                    future = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Task to remove cancelled tasks from the scheduler to keep a memory leak
+     * from occurring
+     */
+    class SchedulePurger implements Runnable {
+
+        public void run() {
+            scheduler.purge();
+        }
+
+    }
+
+}

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockTask.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockTask.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockTask.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/LockTask.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,51 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class LockTask implements Runnable {
+    
+    private static Log log = LogFactory.getLog(LockTask.class);
+    
+    private String lockId;
+    private String owner;
+    private LockManager mgr;
+    
+    public LockTask(String lockId, String owner, LockManager mgr) {
+        this.lockId = lockId;
+        this.owner = owner;
+        this.mgr = mgr;
+    }
+
+    public void run() {
+        try {
+            if (log.isDebugEnabled()){
+                log.debug("LockTimeout fired for lockId="+lockId+" owner="+owner);
+            }
+            mgr.release(lockId, owner);
+        } catch (NotCurrentOwnerException e) {
+            //If we are no ,onger the owner, then oh well....
+            //This really should never/ever happen
+            log.error(e);
+        }
+    }
+
+}
\ No newline at end of file

Added: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/NotCurrentOwnerException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/NotCurrentOwnerException.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/NotCurrentOwnerException.java
(added)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/lock/NotCurrentOwnerException.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,40 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+public class NotCurrentOwnerException extends Exception {
+
+    private static final long serialVersionUID = -1000342299038833797L;
+
+    public NotCurrentOwnerException() {
+    }
+
+    public NotCurrentOwnerException(String arg0) {
+        super(arg0);
+    }
+
+    public NotCurrentOwnerException(Throwable arg0) {
+        super(arg0);
+    }
+
+    public NotCurrentOwnerException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+    }
+
+}

Modified: geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/transports/CommandVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/transports/CommandVisitor.java?view=diff&rev=503896&r1=503895&r2=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/transports/CommandVisitor.java
(original)
+++ geronimo/sandbox/gcache/common/src/main/java/org/apache/geronimo/gcache/transports/CommandVisitor.java
Mon Feb  5 14:10:58 2007
@@ -18,17 +18,19 @@
  */
 package org.apache.geronimo.gcache.transports;
 
+import java.io.IOException;
+
 import org.apache.geronimo.gcache.command.BulkSendCommand;
 import org.apache.geronimo.gcache.command.ClearCacheCommand;
 import org.apache.geronimo.gcache.command.GetCacheCommand;
+import org.apache.geronimo.gcache.command.LockCommand;
 import org.apache.geronimo.gcache.command.MessageAckCommand;
 import org.apache.geronimo.gcache.command.PutEntryCommand;
 import org.apache.geronimo.gcache.command.PutSessionCommand;
+import org.apache.geronimo.gcache.command.ReleaseLockCommand;
 import org.apache.geronimo.gcache.command.RemoveEntryCommand;
 import org.apache.geronimo.gcache.command.RemoveSessionCommand;
 
-import java.io.IOException;
-
 public interface CommandVisitor {
 
     public void processRemoveSession(RemoveSessionCommand command);
@@ -39,4 +41,6 @@
     public void processGetCache(GetCacheCommand command);
     public void processClearCache(ClearCacheCommand command);
     public void processBulkSend(BulkSendCommand command);
+    public void processLockSession(LockCommand command);
+    public void processReleaseLockSession(ReleaseLockCommand command);
 }

Added: geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockClient.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockClient.java
(added)
+++ geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockClient.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,114 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class LockClient extends Thread {
+    public static final int NO_SIGNAL = 0;
+
+    public static final int LOCK = 1;
+
+    public static final int RELEASE = 2;
+
+    private boolean running = false;
+
+    private LockManager mgr = null;
+
+    private String id = null;
+
+    private AtomicInteger signal = new AtomicInteger(NO_SIGNAL);
+
+    private Object monitor = new Object();
+
+    private AtomicBoolean releaseFailure = new AtomicBoolean(false);
+
+    public LockClient(LockManager mgr, String id) {
+        this.mgr = mgr;
+        this.id = id;
+    }
+
+    public boolean hasAcquiredLock() {
+        return mgr.hasLock("CACHE", "SESSION", id);
+    }
+
+    public boolean hasReleaseFailure() {
+        return releaseFailure.get();
+    }
+
+    public void shutdown() throws Exception {
+        running = false;
+        synchronized (monitor) {
+            monitor.notify();
+        }
+        //Allow the thread to handle the signal
+        Thread.sleep(100);
+    }
+
+    public void signalLock() throws Exception {
+        signal.set(LOCK);
+        releaseFailure.set(false);
+        synchronized (monitor) {
+            monitor.notify();
+        }
+        //Allow the thread to handle the signal
+        Thread.sleep(100);
+    }
+
+    public void signalRelease() throws Exception {
+        signal.set(RELEASE);
+        releaseFailure.set(false);
+        synchronized (monitor) {
+            monitor.notify();
+        }
+        //Allow the thread to handle the signal
+        Thread.sleep(100);
+    }
+
+    public void run() {
+        running = true;
+        monitor = new Object();
+        while (running) {
+            try {
+                synchronized (monitor) {
+                    monitor.wait();
+                }
+                switch (signal.get()) {
+                case (LOCK):
+                    signal.set(NO_SIGNAL);
+                    mgr.acquire("CACHE", "SESSION", id);
+                    break;
+                case (RELEASE):
+                    signal.set(NO_SIGNAL);
+                    try {
+                        mgr.release("CACHE", "SESSION", id);
+                    } catch (NotCurrentOwnerException e) {
+                        releaseFailure.set(true);
+                    }
+                    break;
+                }
+            } catch (InterruptedException e) {
+                // Thread is done
+                return;
+            }
+        }
+    }
+}
+

Added: geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTest.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTest.java
(added)
+++ geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTest.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,91 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class LockManagerTest {
+    private LockManager mgr;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        mgr = new LockManager();
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void shutdown() throws Exception {
+        mgr.destroy();
+    }
+
+    @Test
+    public void testLockManager() throws Exception {
+        LockClient clientA = new LockClient(mgr, "A");
+        clientA.start();
+        LockClient clientB = new LockClient(mgr, "B");
+        clientB.start();
+
+        // Give the threads a .5 sec to fire up
+        Thread.sleep(500);
+
+        // Lock Client A
+        clientA.signalLock();
+
+        // Lock Client B
+        clientB.signalLock();
+
+        // Client A should have the lock
+        assert (clientA.hasAcquiredLock());
+
+        // Client B should not
+        assert (!clientB.hasAcquiredLock());
+
+        // Release Client A
+        clientA.signalRelease();
+
+        // Client A should not have a lock
+        assert (!clientA.hasAcquiredLock());
+
+        // Client B should have the lock
+        assert (clientB.hasAcquiredLock());
+
+        // Try to release a lock not owned by client A (invalid condition)
+        assert (!clientA.hasReleaseFailure());
+        clientA.signalRelease();
+        assert (clientA.hasReleaseFailure());
+
+        // try to lock client A
+        clientA.signalLock();
+
+        // Client A should not have a lock since B has it
+        assert (!clientA.hasAcquiredLock());
+
+        // Release client B's lock
+        clientB.signalRelease();
+
+        // Client A should now have the lock
+        assert (clientA.hasAcquiredLock());
+
+        clientA.shutdown();
+        clientB.shutdown();
+
+    }
+
+}

Added: geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTimeoutTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTimeoutTest.java?view=auto&rev=503896
==============================================================================
--- geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTimeoutTest.java
(added)
+++ geronimo/sandbox/gcache/common/src/test/java/org/apache/geronimo/gcache/lock/LockManagerTimeoutTest.java
Mon Feb  5 14:10:58 2007
@@ -0,0 +1,80 @@
+/*
+ * 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.geronimo.gcache.lock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class LockManagerTimeoutTest {
+    
+    private static Log log = LogFactory.getLog(LockManagerTimeoutTest.class);
+    
+    private LockManager mgr;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        //Setup a 2 second timeout so we don't have to wait 10 seconds
+        mgr = new LockManager(LockManager.DEFAULT_THREAD_POOL_SIZE, 3000);
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void shutdown() throws Exception {
+        mgr.destroy();
+    }
+
+    @Test
+    public void testTimeout() throws Exception{
+
+        LockClient clientA = new LockClient(mgr, "A");
+        clientA.start();
+        LockClient clientB = new LockClient(mgr, "B");
+        clientB.start();
+
+        // Give the threads a .5 sec to fire up
+        Thread.sleep(500);
+
+        // Lock Client A
+        clientA.signalLock();
+
+        // Lock Client B
+        clientB.signalLock();
+
+        // Client A should have the lock
+        assert (clientA.hasAcquiredLock());
+
+        // Client B should not
+        assert (!clientB.hasAcquiredLock());
+        
+        log.info("Waiting for 3 second timeout to occur...");
+        
+        //Sleep for the allotted amount of time and then some (for slower processors to process
the release)
+        Thread.sleep(3200);
+        
+        //Client A should have forced released the lock
+        assert (!clientA.hasAcquiredLock());
+        
+        // Client B should have the lock
+        assert (clientB.hasAcquiredLock());
+        
+    }
+
+}

Modified: geronimo/sandbox/gcache/server/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPCommandVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gcache/server/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPCommandVisitor.java?view=diff&rev=503896&r1=503895&r2=503896
==============================================================================
--- geronimo/sandbox/gcache/server/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPCommandVisitor.java
(original)
+++ geronimo/sandbox/gcache/server/src/main/java/org/apache/geronimo/gcache/transports/tcp/TCPCommandVisitor.java
Mon Feb  5 14:10:58 2007
@@ -33,9 +33,11 @@
 import org.apache.geronimo.gcache.command.BulkSendCommand;
 import org.apache.geronimo.gcache.command.ClearCacheCommand;
 import org.apache.geronimo.gcache.command.GetCacheCommand;
+import org.apache.geronimo.gcache.command.LockCommand;
 import org.apache.geronimo.gcache.command.MessageAckCommand;
 import org.apache.geronimo.gcache.command.PutEntryCommand;
 import org.apache.geronimo.gcache.command.PutSessionCommand;
+import org.apache.geronimo.gcache.command.ReleaseLockCommand;
 import org.apache.geronimo.gcache.command.RemoveEntryCommand;
 import org.apache.geronimo.gcache.command.RemoveSessionCommand;
 import org.apache.mina.common.IoSession;
@@ -217,6 +219,14 @@
 
         // Do not send an ack here, the filter will send it once all
         // of the following commands have been received
+    }
+
+    public void processLockSession(LockCommand command) {
+        
+    }
+
+    public void processReleaseLockSession(ReleaseLockCommand command) {
+        
     }
 
 }



Mime
View raw message