[jboss-cvs] JBossAS SVN: r104450 - trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue May 4 13:48:52 EDT 2010
Author: bstansberry at jboss.com
Date: 2010-05-04 13:48:51 -0400 (Tue, 04 May 2010)
New Revision: 104450
Removed:
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/ClusterLockState.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalLockHandler.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/RemoteLockResponse.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/TimeoutException.java
trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java
Log:
[JBAS-7992] Remove unused HASessionState stuff
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,576 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-import org.jboss.ha.framework.interfaces.HAPartition.HAMembershipListener;
-import org.jboss.ha.framework.server.lock.ClusterLockState.State;
-import org.jboss.logging.Logger;
-
-/**
- * Base class for cluster-wide lock implementations.
- *
- * @author Brian Stansberry
- *
- * @version $Revision:$
- */
-public abstract class AbstractClusterLockSupport implements HAMembershipListener
-{
- public static final Class<?>[] REMOTE_LOCK_TYPES = new Class[]{Serializable.class, ClusterNode.class, long.class};
- public static final Class<?>[] RELEASE_REMOTE_LOCK_TYPES = new Class[]{Serializable.class, ClusterNode.class};
-
- /**
- * Object the HAPartition can invoke on. This class is static as
- * an aid in unit testing.
- */
- public static class RpcTarget
- {
- private final AbstractClusterLockSupport mgr;
-
- private RpcTarget(AbstractClusterLockSupport mgr)
- {
- this.mgr = mgr;
- }
-
- public RemoteLockResponse remoteLock(Serializable categoryName, ClusterNode caller, long timeout)
- {
- return mgr.remoteLock(categoryName, caller, timeout);
- }
-
- public void releaseRemoteLock(Serializable categoryName, ClusterNode caller)
- {
- mgr.releaseRemoteLock(categoryName, caller);
- }
- }
-
- protected final Logger log = Logger.getLogger(getClass());
-
- private final ConcurrentMap<Serializable, ClusterLockState> lockStates = new ConcurrentHashMap<Serializable, ClusterLockState>();
- private final ConcurrentMap<ClusterNode, Set<ClusterLockState>> lockStatesByOwner = new ConcurrentHashMap<ClusterNode, Set<ClusterLockState>>();
- private ClusterNode me;
- private final String serviceHAName;
- private final HAPartition partition;
- private final LocalLockHandler localHandler;
- private final List<ClusterNode> members = new CopyOnWriteArrayList<ClusterNode>();
-// private final boolean supportLocalOnly;
- private RpcTarget rpcTarget;
-
- public AbstractClusterLockSupport(String serviceHAName,
- HAPartition partition,
- LocalLockHandler handler)
- {
- if (serviceHAName == null)
- {
- throw new IllegalArgumentException("serviceHAName is null");
- }
- if (partition == null)
- {
- throw new IllegalArgumentException("partition is null");
- }
- if (handler == null)
- {
- throw new IllegalArgumentException("localHandler is null");
- }
-
- this.partition = partition;
- this.localHandler = handler;
- this.serviceHAName = serviceHAName;
- }
-
- // -------------------------------------------------------------- Properties
-
- public HAPartition getPartition()
- {
- return partition;
- }
-
- public String getServiceHAName()
- {
- return serviceHAName;
- }
-
- public LocalLockHandler getLocalHandler()
- {
- return localHandler;
- }
-
- // ------------------------------------------------------ ClusterLockManager
-
- public boolean lock(Serializable lockId, long timeout)
- {
- if (this.rpcTarget == null)
- {
- throw new IllegalStateException("Must call start() before first call to lock()");
- }
- ClusterLockState category = getClusterLockState(lockId, true);
-
- long left = timeout > 0 ? timeout : Long.MAX_VALUE;
- long start = System.currentTimeMillis();
- while (left > 0)
- {
- // Another node we lost to who should take precedence
- // over ourself in competition for the lock
- ClusterNode superiorCompetitor = null;
-
- // Only continue if category is unlocked
- if (category.state.compareAndSet(ClusterLockState.State.UNLOCKED, ClusterLockState.State.REMOTE_LOCKING))
- {
- // Category state is now REMOTE_LOCKING, so other nodes will fail
- // in attempts to acquire on this node unless the caller is "superior"
-
- boolean success = false;
- try
- {
- // Get the lock on all other nodes in the cluster
-
- List<?> rsps = partition.callMethodOnCluster(getServiceHAName(),
- "remoteLock", new Object[]{lockId, me, new Long(left)},
- REMOTE_LOCK_TYPES, true);
-
- boolean remoteLocked = true;
- if (rsps != null)
- {
- for (Object rsp : rsps)
- {
- if ((rsp instanceof RemoteLockResponse) == false)
- {
- remoteLocked = false;
- }
- else if (((RemoteLockResponse) rsp).flag != RemoteLockResponse.Flag.OK)
- {
- RemoteLockResponse curRsp = (RemoteLockResponse) rsp;
- remoteLocked = false;
- if (superiorCompetitor == null)
- {
- superiorCompetitor = getSuperiorCompetitor(curRsp.holder);
- log.debug("Received " + curRsp.flag + " response from " +
- curRsp.responder + " -- reports lock is held by " + curRsp.holder);
- }
- }
- }
- }
- else if ((members.size() == 1 && members.contains(me)) || members.size() == 0)
- {
- // no peers
- remoteLocked = true;
- }
-
- if (remoteLocked)
- {
- // Bail if someone else locked our node while we were locking
- // others.
- if (category.state.compareAndSet(ClusterLockState.State.REMOTE_LOCKING, ClusterLockState.State.LOCAL_LOCKING))
- {
- // Now we are in LOCAL_LOCKING phase which will cause
- // us to reject incoming remote requests
-
- // Now see if we can lock our own node
- long localTimeout = left - (System.currentTimeMillis() - start);
- if (getLock(lockId, category, me, localTimeout).flag == RemoteLockResponse.Flag.OK)
- {
- success = true;
- return true;
- }
- // else either 1) there was a race with a remote caller or
- // 2) some other activity locally is preventing our
- // acquisition of the local lock. Either way back off
- // and then retry
- }
-
- // Find out if we couldn't acquire because someone with
- // precedence has the lock
- superiorCompetitor = getSuperiorCompetitor(category.getHolder());
- }
- }
- catch (RuntimeException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- finally
- {
- if (!success)
- {
- cleanup(lockId, category);
- }
- }
- }
-
- // We failed for some reason. Pause to let things clear before trying again.
- // If we've detected we are competing with someone else who is
- // "superior" pause longer to let them proceed first.
- long backoff = computeBackoff(timeout, start, left, superiorCompetitor == null);
- if (backoff > 0)
- {
- try
- {
- Thread.sleep(backoff);
- }
- catch (InterruptedException e)
- {
- Thread.currentThread().interrupt();
- break;
- }
- }
-
- if (category.state.get() == ClusterLockState.State.INVALID)
- {
- // Someone invalidated our category; get a new one
- category = getClusterLockState(lockId, true);
- }
-
- long now = System.currentTimeMillis();
- left -= (now - start);
- start = now;
- }
-
- return false;
- }
-
- public abstract void unlock(Serializable lockId);
-
- public String getPartitionName()
- {
- return partition.getPartitionName();
- }
-
- public ClusterNode getLocalClusterNode()
- {
- return this.me;
- }
-
- public List<ClusterNode> getCurrentView()
- {
- return new ArrayList<ClusterNode>(members);
- }
-
- public void start() throws Exception
- {
- this.me = this.partition.getClusterNode();
- this.localHandler.setLocalNode(this.me);
-
- this.rpcTarget = new RpcTarget(this);
- this.partition.registerRPCHandler(this.serviceHAName, this.rpcTarget);
- this.partition.registerMembershipListener(this);
-
- Vector<ClusterNode> allMembers = new Vector<ClusterNode>();
- for (ClusterNode node : this.partition.getClusterNodes())
- {
- allMembers.add(node);
- }
- membershipChanged(new Vector<ClusterNode>(), allMembers, allMembers);
- }
-
- public void stop() throws Exception
- {
- if (this.rpcTarget != null)
- {
- this.partition.unregisterRPCHandler(this.serviceHAName, this.rpcTarget);
- this.rpcTarget = null;
- this.partition.unregisterMembershipListener(this);
- Vector<ClusterNode> dead = new Vector<ClusterNode>(members);
- Vector<ClusterNode> empty = new Vector<ClusterNode>();
- membershipChanged(dead, empty, empty);
- this.me = null;
- }
- }
-
- // ---------------------------------------------------- HAMembershipListener
-
- public synchronized void membershipChanged(Vector<ClusterNode> deadMembers, Vector<ClusterNode> newMembers, Vector<ClusterNode> allMembers)
- {
- this.members.clear();
- this.members.addAll(allMembers);
-
- Set<ClusterNode> toClean = lockStatesByOwner.keySet();
- toClean.removeAll(this.members);
- for (ClusterNode deadMember : toClean)
- {
- Set<ClusterLockState> deadMemberLocks = lockStatesByOwner.remove(deadMember);
- if (deadMemberLocks != null)
- {
- synchronized (deadMemberLocks)
- {
- // We're going to iterate and make a call that removes from set,
- // so iterate over a copy to avoid ConcurrentModificationException
- Set<ClusterLockState> copy = new HashSet<ClusterLockState>(deadMemberLocks);
- for (ClusterLockState lockState : copy)
- {
- releaseRemoteLock(lockState.lockId, (ClusterNode) deadMember);
- }
- }
- }
-
- }
- }
-
- // --------------------------------------------------------------- Protected
-
- protected abstract RemoteLockResponse handleLockSuccess(ClusterLockState lockState, ClusterNode caller);
-
- protected abstract ClusterLockState getClusterLockState(Serializable categoryName);
-
- protected abstract RemoteLockResponse yieldLock(ClusterLockState lockState, ClusterNode caller, long timeout);
-
- protected void recordLockHolder(ClusterLockState lockState, ClusterNode caller)
- {
- if (lockState.holder != null)
- {
- Set<ClusterLockState> memberLocks = getLocksHeldByMember(lockState.holder);
- synchronized (memberLocks)
- {
- memberLocks.remove(lockState);
- }
- }
-
- if (me.equals(caller) == false)
- {
- Set<ClusterLockState> memberLocks = getLocksHeldByMember(caller);
- synchronized (memberLocks)
- {
- memberLocks.add(lockState);
- }
- }
-
- lockState.lock(caller);
- }
-
- protected ClusterLockState getClusterLockState(Serializable lockName, boolean create)
- {
- ClusterLockState category = lockStates.get(lockName);
- if (category == null && create)
- {
- category = new ClusterLockState(lockName);
- ClusterLockState existing = lockStates.putIfAbsent(lockName, category);
- if (existing != null)
- {
- category = existing;
- }
- }
- return category;
- }
-
- protected void removeLockState(ClusterLockState lockState)
- {
- lockStates.remove(lockState.lockId, lockState);
- }
-
- // ----------------------------------------------------------------- Private
-
- /**
- * Called by a remote node via RpcTarget.
- */
- private RemoteLockResponse remoteLock(Serializable lockName, ClusterNode caller, long timeout)
- {
- RemoteLockResponse response = null;
- ClusterLockState lockState = getClusterLockState(lockName);
- if (lockState == null)
- {
- // unknown == OK
- return new RemoteLockResponse(me, RemoteLockResponse.Flag.OK);
- }
-
- switch (lockState.state.get())
- {
- case UNLOCKED:
- // Remote callers can race for the local lock
- response = getLock(lockName, lockState, caller, timeout);
- break;
- case REMOTE_LOCKING:
- if (me.equals(caller))
- {
- log.warn("Received remoteLock call from self");
- response = new RemoteLockResponse(me, RemoteLockResponse.Flag.OK);
- }
- else if (getSuperiorCompetitor(caller) == null)
- {
- // I want the lock and I take precedence
- response = new RemoteLockResponse(me, RemoteLockResponse.Flag.REJECT, me);
- }
- else
- {
- // I want the lock but caller takes precedence; let
- // them acquire local lock and I'll fail
- response = getLock(lockName, lockState, caller, timeout);
- }
- break;
- case LOCAL_LOCKING:
- // I've gotten OK responses from everyone and am about
- // to acquire local lock, so reject caller
- response = new RemoteLockResponse(me, RemoteLockResponse.Flag.REJECT, me);
- break;
- case LOCKED:
- // See if I have the lock and will give it up
- response = yieldLock(lockState, caller, timeout);
- break;
- case INVALID:
- // We've given up the lock since we got the category and the
- // thread that caused that is trying to discard the unneeded
- // category.
- // Call in again and see what our current state is
- Thread.yield();
- response = remoteLock(lockName, caller, timeout);
- break;
- }
-
- return response;
- }
-
- /**
- * Called by a remote node via RpcTarget.
- */
- private void releaseRemoteLock(Serializable categoryName, ClusterNode caller)
- {
- ClusterLockState lockState = getClusterLockState(categoryName, false);
- if (lockState != null && lockState.state.get() == State.LOCKED)
- {
- if (caller.equals(localHandler.getLockHolder(categoryName)))
- {
- // Throw away the category as a cleanup exercise
- lockState.invalidate();
- localHandler.unlockFromCluster(categoryName, caller);
- Set<ClusterLockState> memberLocks = getLocksHeldByMember(caller);
- synchronized (memberLocks)
- {
- memberLocks.remove(lockState);
- }
- removeLockState(lockState);
- }
- }
-
- }
-
- /** See if <code>caller</code> comes before us in the members list */
- private ClusterNode getSuperiorCompetitor(ClusterNode caller)
- {
- if (caller == null)
- return null;
-
- for (ClusterNode node : members)
- {
- if (me.equals(node))
- {
- break;
- }
- else if (caller.equals(node))
- {
- return caller;
- }
- }
-
- return null;
- }
-
- /**
- * Always call this with a lock on the Category.
- */
- protected RemoteLockResponse getLock(Serializable categoryName, ClusterLockState category,
- ClusterNode caller, long timeout)
- {
- RemoteLockResponse response;
- try
- {
- localHandler.lockFromCluster(categoryName, caller, timeout);
- }
- catch (InterruptedException e)
- {
- Thread.currentThread().interrupt();
- log.error("Caught InterruptedException; Failing request by " + caller + " to lock " + categoryName);
- return new RemoteLockResponse(me, RemoteLockResponse.Flag.FAIL, localHandler.getLockHolder(categoryName));
- }
- catch (TimeoutException t)
- {
- return new RemoteLockResponse(me, RemoteLockResponse.Flag.FAIL, t.getOwner());
- }
-
- response = handleLockSuccess(category, caller);
- return response;
- }
-
- private Set<ClusterLockState> getLocksHeldByMember(ClusterNode member)
- {
- Set<ClusterLockState> memberCategories = lockStatesByOwner.get(member);
- if (memberCategories == null)
- {
- memberCategories = new HashSet<ClusterLockState>();
- Set<ClusterLockState> existing = lockStatesByOwner.putIfAbsent(member, memberCategories);
- if (existing != null)
- {
- memberCategories = existing;
- }
- }
- return memberCategories;
- }
-
- /** Back out of a failed attempt by the local node to lock */
- private void cleanup(Serializable categoryName, ClusterLockState category)
- {
- try
- {
- partition.callMethodOnCluster(getServiceHAName(), "releaseRemoteLock", new Object[]{categoryName, me}, RELEASE_REMOTE_LOCK_TYPES, true);
- }
- catch (RuntimeException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("Failed releasing remote lock", e);
- }
- finally
- {
- if (category.state.compareAndSet(ClusterLockState.State.REMOTE_LOCKING, ClusterLockState.State.UNLOCKED) == false)
- {
- category.state.compareAndSet(ClusterLockState.State.LOCAL_LOCKING, ClusterLockState.State.UNLOCKED);
- }
- }
- }
-
- private static long computeBackoff(long initialTimeout, long start, long left, boolean superiorCompetitor)
- {
- long remain = left - (System.currentTimeMillis() - start);
- // Don't spam the cluster
- if (remain < Math.min(initialTimeout / 5, 15))
- {
- return remain;
- }
-
- long max = superiorCompetitor ? 100 : 250;
- long min = remain / 3;
- return Math.min(max, min);
- }
-}
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/ClusterLockState.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/ClusterLockState.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/ClusterLockState.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,92 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-
-/**
- *
- * @author Brian Stansberry
- *
- * @version $Revision:$
- */
-public class ClusterLockState
-{
- /** Lock status of a category */
- public enum State
- {
- /** No one has the lock and local node is not attempting to acquire */
- UNLOCKED,
- /** Local node is attempting to acquire lock across cluster */
- REMOTE_LOCKING,
- /** Local node has lock across cluster, now attempting locally */
- LOCAL_LOCKING,
- /** The lock is held locally */
- LOCKED,
- /**
- * This object has been removed from the categories map and
- * should be discarded
- */
- INVALID
- }
- final Serializable lockId;
- final AtomicReference<ClusterLockState.State> state = new AtomicReference<ClusterLockState.State>(State.UNLOCKED);
- ClusterNode holder;
-
- ClusterLockState(Serializable lockId)
- {
- if (lockId == null)
- {
- throw new IllegalArgumentException("lockId is null");
- }
- this.lockId = lockId;
- }
-
- public synchronized ClusterNode getHolder()
- {
- return holder;
- }
-
- public synchronized void invalidate()
- {
- this.state.set(State.INVALID);
- this.holder = null;
- }
-
- public synchronized void lock(ClusterNode holder)
- {
- this.state.set(State.LOCKED);
- this.holder = holder;
- }
-
- public synchronized void release()
- {
- if (this.state.compareAndSet(State.LOCKED, State.UNLOCKED))
- {
- this.holder = null;
- }
- }
-}
\ No newline at end of file
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,229 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.LockSupport;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-
-/**
- * @author Brian Stansberry
- *
- * @version $Revision:$
- */
-public class LocalAndClusterLockManager
-{
-
- private class LocalLock
- {
- private volatile ClusterNode holder;
- private final AtomicBoolean locked = new AtomicBoolean(false);
- private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
-
-
- private void lock(ClusterNode caller, long timeout) throws TimeoutException
- {
- long deadline = System.currentTimeMillis() + timeout;
- boolean wasInterrupted = false;
- Thread current = Thread.currentThread();
- waiters.add(current);
-
- try
- {
- // Block while not first in queue or cannot acquire lock
- while (waiters.peek() != current ||
- !locked.compareAndSet(false, true))
- {
- LockSupport.parkUntil(deadline);
- if (Thread.interrupted()) // ignore interrupts while waiting
- wasInterrupted = true;
- if (System.currentTimeMillis() >= deadline)
- {
- if (waiters.peek() != current ||
- !locked.compareAndSet(false, true))
- {
- throw new TimeoutException(this.holder);
- }
- break;
- }
- }
-
- if (locked.get())
- {
- holder = caller;
- }
- else
- {
- throw new TimeoutException(this.holder);
- }
- }
- finally
- {
- waiters.remove();
- if (wasInterrupted) // reassert interrupt status on exit
- current.interrupt();
- }
- }
-
- private void unlock(ClusterNode caller)
- {
- if (caller.equals(holder))
- {
- locked.set(false);
- holder = null;
- LockSupport.unpark(waiters.peek());
- }
- }
-
-
- }
-
- /** Handles callbacks from the cluster lock support object */
- private class ClusterHandler implements LocalLockHandler
- {
- // ----------------------------------------------------- LocalLockHandler
-
- public ClusterNode getLocalNode(ClusterNode localNode)
- {
- return LocalAndClusterLockManager.this.localNode;
- }
-
- public void setLocalNode(ClusterNode localNode)
- {
- LocalAndClusterLockManager.this.localNode = localNode;
- }
-
- public void lockFromCluster(Serializable lockName, ClusterNode caller, long timeout) throws TimeoutException,
- InterruptedException
- {
- LocalAndClusterLockManager.this.doLock(lockName, caller, timeout);
- }
-
- public ClusterNode getLockHolder(Serializable lockName)
- {
- LocalLock lock = LocalAndClusterLockManager.this.getLocalLock(lockName, false);
- return lock == null ? null : lock.holder;
- }
-
- public void unlockFromCluster(Serializable lockName, ClusterNode caller)
- {
- LocalAndClusterLockManager.this.doUnlock(lockName, caller);
- }
-
- }
-
- private ClusterNode localNode;
- private ConcurrentMap<Serializable, LocalLock> localLocks = new ConcurrentHashMap<Serializable, LocalLock>();
- private final NonGloballyExclusiveClusterLockSupport clusterSupport;
-
- public LocalAndClusterLockManager(String serviceHAName, HAPartition partition)
- {
- ClusterHandler handler = new ClusterHandler();
- clusterSupport = new NonGloballyExclusiveClusterLockSupport(serviceHAName, partition, handler);
- }
-
- // ----------------------------------------------------------------- Public
-
- public void lockLocally(Serializable lockName, long timeout)
- throws TimeoutException, InterruptedException
- {
- if (this.localNode == null)
- {
- throw new IllegalStateException("Null localNode");
- }
-
- doLock(lockName, this.localNode, timeout);
- }
-
- public void unlockLocally(Serializable lockName)
- {
- if (this.localNode == null)
- {
- throw new IllegalStateException("Null localNode");
- }
-
- doUnlock(lockName, this.localNode);
- }
-
- public void lockGlobally(Serializable lockName, long timeout)
- throws TimeoutException, InterruptedException
- {
- this.clusterSupport.lock(lockName, timeout);
- }
-
- public void unlockGlobally(Serializable lockName)
- {
- this.clusterSupport.unlock(lockName);
- }
-
- public void start() throws Exception
- {
- this.clusterSupport.start();
- }
-
- public void stop() throws Exception
- {
- this.clusterSupport.stop();
- }
-
- // ----------------------------------------------------------------- Private
-
- private LocalLock getLocalLock(Serializable categoryName, boolean create)
- {
- LocalLock category = localLocks.get(categoryName);
- if (category == null && create)
- {
- category = new LocalLock();
- LocalLock existing = localLocks.putIfAbsent(categoryName, category);
- if (existing != null)
- {
- category = existing;
- }
- }
- return category;
- }
-
- private void doLock(Serializable lockName, ClusterNode caller, long timeout) throws TimeoutException,
- InterruptedException
- {
- LocalLock lock = getLocalLock(lockName, true);
- lock.lock(caller, timeout);
- }
-
- private void doUnlock(Serializable lockName, ClusterNode caller)
- {
- LocalLock lock = getLocalLock(lockName, false);
- if (lock != null)
- {
- lock.unlock(caller);
- }
- }
-
-}
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalLockHandler.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalLockHandler.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/LocalLockHandler.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,75 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-
-/**
- * Provides local lock coordination for an {@link AbstractClusterLockSupport}.
- *
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-public interface LocalLockHandler
-{
- /**
- * Gets the node the holds the given lock on this node, or <code>null</code>
- * if no node holds the lock on this node.
- *
- * @param lockName
- * @return
- */
- ClusterNode getLockHolder(Serializable lockName);
-
- /**
- * Try to acquire the local lock within the given timeout. If this
- * method returns successfully, the caller has acquired the lock.
- *
- * @param lockName the name of the lock.
- * @param caller the node making the request
- * @param timeout number of ms the caller will accept waiting before
- * the lock acquisition should be considered a failure.
- * A value less than one means wait as long as necessary.
- *
- * @throws TimeoutException if the lock could not be acquired within the
- * specified timeout
- * @throws InterruptedException
- */
- void lockFromCluster(Serializable lockName, ClusterNode caller, long timeout)
- throws TimeoutException, InterruptedException;
-
- /**
- * Release the lock.
- *
- * @param lockName the name of the lock.
- * @param caller the node making the request
- */
- void unlockFromCluster(Serializable lockName, ClusterNode caller);
-
- ClusterNode getLocalNode(ClusterNode localNode);
-
- void setLocalNode(ClusterNode localNode);
-}
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,112 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-
-/**
- * Support class for cluster locking scenarios where threads can hold a
- * local lock on a category but not a cluster-wide lock. Multiple nodes can
- * simultaneously hold a local lock on a category, but none can hold a local
- * lock on a category if the cluster-wide lock is held. Cluster-wide lock cannot
- * be acquired while any node holds a local lock.
- * <p>
- * <strong>NOTE:</strong> This class does not support "upgrades", i.e. scenarios
- * where a thread acquires the local lock and then while holding the local
- * lock attempts to acquire the cluster-wide lock.
- * </p>
- *
- * @author Brian Stansberry
- */
-public class NonGloballyExclusiveClusterLockSupport extends AbstractClusterLockSupport
-{
-
- // ------------------------------------------------------------- Constructor
-
- public NonGloballyExclusiveClusterLockSupport(String serviceHAName,
- HAPartition partition,
- LocalLockHandler handler)
- {
- super(serviceHAName, partition, handler);
- }
-
- // ------------------------------------------------------------------ Public
-
- public void unlock(Serializable lockId)
- {
- ClusterNode myself = getLocalClusterNode();
- if (myself == null)
- {
- throw new IllegalStateException("Must call start() before first call to unlock()");
- }
-
- ClusterLockState lockState = getClusterLockState(lockId, false);
-
- if (lockState != null && myself.equals(lockState.getHolder()))
- {
- getLocalHandler().unlockFromCluster(lockId, myself);
- lockState.release();
-
- try
- {
- getPartition().callMethodOnCluster(getServiceHAName(), "releaseRemoteLock",
- new Object[]{lockId, myself},
- RELEASE_REMOTE_LOCK_TYPES, true);
- }
- catch (RuntimeException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("Failed releasing remote lock", e);
- }
- }
- }
-
- // --------------------------------------------------------------- Protected
-
- @Override
- protected ClusterLockState getClusterLockState(Serializable categoryName)
- {
- return getClusterLockState(categoryName, true);
- }
-
- @Override
- protected RemoteLockResponse yieldLock(ClusterLockState lockState, ClusterNode caller, long timeout)
- {
- return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.REJECT, lockState.getHolder());
- }
-
- @Override
- protected RemoteLockResponse handleLockSuccess(ClusterLockState lockState, ClusterNode caller)
- {
- recordLockHolder(lockState, caller);
- return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.OK);
- }
-
- // ----------------------------------------------------------------- Private
-}
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/RemoteLockResponse.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/RemoteLockResponse.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/RemoteLockResponse.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,44 +0,0 @@
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-
-/**
- * Return value for a "remoteLock" call. This class is public as an
- * aid in unit testing.
- */
-public class RemoteLockResponse implements Serializable
-{
- public enum Flag
- {
- /** Lock acquired on responding node */
- OK,
- /** Attempt to acquire local lock failed */
- FAIL,
- /**
- * Request rejected either because lock is held or
- * local node is attempting to acquire lock.
- */
- REJECT
- }
-
- /** The serialVersionUID */
- private static final long serialVersionUID = -8878607946010425555L;
-
- public final RemoteLockResponse.Flag flag;
- public final ClusterNode holder;
- public final ClusterNode responder;
-
- public RemoteLockResponse(ClusterNode responder, RemoteLockResponse.Flag flag)
- {
- this(responder, flag, null);
- }
-
- public RemoteLockResponse(ClusterNode responder, RemoteLockResponse.Flag flag, ClusterNode holder)
- {
- this.flag = flag;
- this.holder = holder;
- this.responder = responder;
- }
-}
\ No newline at end of file
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/TimeoutException.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/TimeoutException.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/TimeoutException.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-
-/**
- * Thrown to indicate failure to acquire a lock within a specified timeout.
- *
- * @author Brian Stansberry
- */
-public class TimeoutException extends Exception
-{
- /** The serialVersionUID */
- private static final long serialVersionUID = 7786468949269669386L;
-
- private ClusterNode owner;
-
- public TimeoutException(ClusterNode owner)
- {
- super("Unable to acquire lock as it is held by " + (owner == null ? "unknown" : owner));
- this.owner = owner;
- }
-
- public ClusterNode getOwner()
- {
- return owner;
- }
-}
Deleted: trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java 2010-05-04 17:34:16 UTC (rev 104449)
+++ trunk/cluster/src/main/java/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java 2010-05-04 17:48:51 UTC (rev 104450)
@@ -1,114 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ha.framework.server.lock;
-
-import java.io.Serializable;
-
-import org.jboss.ha.framework.interfaces.ClusterNode;
-import org.jboss.ha.framework.interfaces.HAPartition;
-
-/**
- * Support class for cluster locking scenarios where threads cannot acquire
- * a local lock unless the node owns a cluster-wide lock, but where the node
- * owning the cluster-wide lock will yield it to another node if no thread
- * has a local lock. Use case for this is scenarios like session management
- * where a node needs to acquire ownership of a cluster-wide lock for a session,
- * but then once acquired wishes to handle multiple calls for the session without
- * make cluster-wide locking calls. The node handling the session would acquire
- * the cluster-wide lock if it doesn't have it and thereafter would only use
- * local locks; if another node received a request for the session it would
- * request the lock and the first node would release it if no local locks are
- * held.
- *
- * @author Brian Stansberry
- */
-public class YieldingGloballyExclusiveClusterLockSupport extends AbstractClusterLockSupport
-{
- public YieldingGloballyExclusiveClusterLockSupport(String serviceHAName,
- HAPartition partition,
- LocalLockHandler handler)
- {
- super(serviceHAName, partition, handler);
- }
-
- // ------------------------------------------------------ ClusterLockManager
-
- public void unlock(Serializable lockId)
- {
- ClusterNode myself = getLocalClusterNode();
- if (myself == null)
- {
- throw new IllegalStateException("Must call start() before first call to unlock()");
- }
-
- ClusterLockState category = getClusterLockState(lockId, false);
-
- if (category != null && myself.equals(category.getHolder()))
- {
- category.invalidate();
- getLocalHandler().unlockFromCluster(lockId, myself);
- removeLockState(category);
- }
- }
-
- // --------------------------------------------------------------- Protected
-
- @Override
- protected ClusterLockState getClusterLockState(Serializable categoryName)
- {
- return getClusterLockState(categoryName, false);
- }
-
- @Override
- protected RemoteLockResponse yieldLock(ClusterLockState lockState, ClusterNode caller, long timeout)
- {
- if (getLocalClusterNode().equals(lockState.getHolder()))
- {
- return getLock(lockState.lockId, lockState, caller, timeout);
- }
- else
- {
- return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.REJECT, lockState.getHolder());
- }
- }
-
- @Override
- protected RemoteLockResponse handleLockSuccess(ClusterLockState lockState, ClusterNode caller)
- {
- if (getLocalClusterNode().equals(caller))
- {
- recordLockHolder(lockState, caller);
- }
- else
- {
- // Caller succeeded, but since this node doesn't hold the
- // lock we don't want to hold the category in our map any longer
- lockState.invalidate();
- removeLockState(lockState);
- }
- return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.OK);
- }
-
-
- // ----------------------------------------------------------------- Private
-}
More information about the jboss-cvs-commits
mailing list