Author: kwright
Date: Mon Nov 25 14:41:36 2013
New Revision: 1545304
URL: http://svn.apache.org/r1545304
Log:
Revamp ILockManager registration logic to remove requirement for external
locking during cleanup.
Added:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
(with props)
Modified:
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentRun.java
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentStop.java
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ILockManager.java
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
Modified:
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentRun.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentRun.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentRun.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentRun.java
Mon Nov 25 14:41:36 2013
@@ -51,7 +51,7 @@ public class AgentRun extends BaseAgents
// AgentStop only, and AgentStop will wait until all services become
inactive before exiting.
String processID = ManifoldCF.getProcessID();
ILockManager lockManager = LockManagerFactory.make(tc);
- lockManager.registerServiceBeginServiceActivity(agentServiceType,
processID);
+ lockManager.registerServiceBeginServiceActivity(agentServiceType,
processID, null);
try
{
// Register a shutdown hook to make sure we signal that the main agents
process is going inactive.
Modified:
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentStop.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentStop.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentStop.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/AgentStop.java
Mon Nov 25 14:41:36 2013
@@ -44,17 +44,8 @@ public class AgentStop extends BaseAgent
while (true)
{
// Check to see if services are down yet
- String[] agents =
lockManager.getRegisteredServices(AgentRun.agentServiceType);
- boolean alive = false;
- for (String agent : agents)
- {
- if (lockManager.checkServiceActive(AgentRun.agentServiceType, agent))
- {
- alive = true;
- break;
- }
- }
- if (!alive)
+ int count = lockManager.countActiveServices(AgentRun.agentServiceType);
+ if (count == 0)
break;
try
{
Modified:
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
Mon Nov 25 14:41:36 2013
@@ -198,13 +198,6 @@ public class ManifoldCF extends org.apac
}
}
- protected final static String agentClassLockPrefix = "_AGENTCLASSLOCK_";
-
- protected static String getAgentsClassLockName(String agentClassName)
- {
- return agentClassLockPrefix + agentClassName;
- }
-
protected static String getAgentsClassServiceType(String agentClassName)
{
return agentServicePrefix + agentClassName;
@@ -241,30 +234,8 @@ public class ManifoldCF extends org.apac
try
{
// Throw a lock, so that cleanup processes and startup processes
don't collide.
- String lockName = getAgentsClassLockName(className);
String serviceType = getAgentsClassServiceType(className);
- boolean firstTime;
- lockManager.enterWriteLock(lockName);
- try
- {
- firstTime =
lockManager.registerServiceBeginServiceActivity(serviceType, processID);
- if (firstTime)
- {
- agent.cleanUpAgentData(threadContext);
- String[] deadAgents =
lockManager.getInactiveServices(serviceType);
- for (String deadAgent : deadAgents)
- {
- lockManager.unregisterService(serviceType, deadAgent);
- }
- }
- }
- finally
- {
- lockManager.leaveWriteLock(lockName);
- }
- // Now initialize agent, being sure to clean up data from previous
incarnations
- if (!firstTime)
- agent.cleanUpAgentData(threadContext, processID);
+ lockManager.registerServiceBeginServiceActivity(serviceType,
processID, new CleanupAgent(threadContext, agent));
// There is a potential race condition where the agent has been
started but hasn't yet appeared in runningHash.
// But having runningHash be the synchronizer for this activity
will prevent any problems.
agent.startAgent(threadContext, processID);
@@ -279,7 +250,7 @@ public class ManifoldCF extends org.apac
}
currentAgentClasses.add(className);
}
-
+
// Go through running hash and look for agents processes that have left
Iterator<String> runningAgentsIterator = runningHash.keySet().iterator();
while (runningAgentsIterator.hasNext())
@@ -303,43 +274,27 @@ public class ManifoldCF extends org.apac
}
}
}
-
+ }
+
+ if (problem != null)
+ throw problem;
+
+ synchronized (runningHash)
+ {
// For every class we're supposed to be running, find registered but
no-longer-active instances and clean
// up after them.
for (String agentsClass : runningHash.keySet())
{
IAgent agent = runningHash.get(agentsClass);
- // Look for dead service instances for this class.
- // This cannot happen at the same time as other processes doing this
check, or at the same
- // time as a service of that class starting up, so we need a lock to
prevent those situations.
- String lockName = getAgentsClassLockName(agentsClass);
- lockManager.enterWriteLock(lockName);
- try
- {
- // Find the derelict agents of this class, clean them up, and
deregister them.
- String agentsClassServiceType =
getAgentsClassServiceType(agentsClass);
- String[] inactiveAgents =
lockManager.getInactiveServices(agentsClassServiceType);
- for (String inactiveAgentProcessID : inactiveAgents)
- {
- agent.cleanUpAgentData(threadContext, inactiveAgentProcessID);
- // Deregister
- lockManager.unregisterService(agentsClassServiceType,
inactiveAgentProcessID);
- }
- }
- catch (ManifoldCFException e)
+ IServiceCleanup cleanup = new CleanupAgent(threadContext, agent);
+ String agentsClassServiceType = getAgentsClassServiceType(agentsClass);
+ while (lockManager.cleanupInactiveService(agentsClassServiceType,
cleanup))
{
- problem = e;
- }
- finally
- {
- lockManager.leaveWriteLock(lockName);
+ // Loop until no more inactive services
}
}
-
}
- if (problem != null)
- throw problem;
- // Done.
+
}
/** Stop all started agents.
@@ -366,6 +321,51 @@ public class ManifoldCF extends org.apac
// Done.
}
+ protected static class CleanupAgent implements IServiceCleanup
+ {
+ protected final IAgent agent;
+ protected final IThreadContext threadContext;
+
+ public CleanupAgent(IThreadContext threadContext, IAgent agent)
+ {
+ this.agent = agent;
+ this.threadContext = threadContext;
+ }
+
+ /** Clean up after the specified service. This method will block any
startup of the specified
+ * service for as long as it runs.
+ *@param serviceName is the name of the service.
+ */
+ @Override
+ public void cleanUpService(String serviceName)
+ throws ManifoldCFException
+ {
+ agent.cleanUpAgentData(threadContext, serviceName);
+ }
+
+ /** Clean up after ALL services of the type on the cluster.
+ */
+ @Override
+ public void cleanUpAllServices()
+ throws ManifoldCFException
+ {
+ agent.cleanUpAgentData(threadContext);
+ }
+
+ /** Perform cluster initialization - that is, whatever is needed presuming
that the
+ * cluster has been down for an indeterminate period of time, but is
otherwise in a clean
+ * state.
+ */
+ @Override
+ public void clusterInit()
+ throws ManifoldCFException
+ {
+ // MHL - we really want a separate clusterInit in agents
+ agent.cleanUpAgentData(threadContext);
+ }
+
+ }
+
/** Signal output connection needs redoing.
* This is called when something external changed on an output connection, and
* therefore all associated documents must be reindexed.
Modified:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ILockManager.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ILockManager.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ILockManager.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ILockManager.java
Mon Nov 25 14:41:36 2013
@@ -43,34 +43,33 @@ public interface ILockManager
* called when the service shuts down. Some ILockManager implementations
require that this take place for
* proper management.
* If the transient registration already exists, it is treated as an error
and an exception will be thrown.
+ * If registration will succeed, then this method may call an appropriate
IServiceCleanup method to clean up either the
+ * current service, or all services on the cluster.
*@param serviceType is the type of service.
*@param serviceName is the name of the service to register.
- *@return true if this is the only active service of this type at this time.
+ *@param cleanup is called to clean up either the current service, or all
services of this type, if no other active service exists
*/
- public boolean registerServiceBeginServiceActivity(String serviceType,
String serviceName)
+ public void registerServiceBeginServiceActivity(String serviceType, String
serviceName, IServiceCleanup cleanup)
throws ManifoldCFException;
- /** Un-register a service.
- * This operation cancels the permanent registration of the specified service.
- * If the service does not exist, this method will do nothing.
- *@param serviceType is the type of service.
- *@param serviceName is the name of the service to unregister.
- */
- public void unregisterService(String serviceType, String serviceName)
- throws ManifoldCFException;
-
- /** List all registered services of a given type.
+ /** Count all active services of a given type.
*@param serviceType is the service type.
- *@return the service names.
+ *@return the count.
*/
- public String[] getRegisteredServices(String serviceType)
+ public int countActiveServices(String serviceType)
throws ManifoldCFException;
- /** List services that are registered but not active.
+ /** Clean up any inactive services found.
+ * Calling this method will invoke cleanup of one inactive service at a time.
+ * If there are no inactive services around, then false will be returned.
+ * Note that this method will block whatever service it finds from starting up
+ * for the time the cleanup is proceeding. At the end of the cleanup, if
+ * successful, the service will be atomically unregistered.
*@param serviceType is the service type.
- *@return the list of service names.
+ *@param cleanup is the object to call to clean up an inactive service.
+ *@return true if there were no cleanup operations necessary.
*/
- public String[] getInactiveServices(String serviceType)
+ public boolean cleanupInactiveService(String serviceType, IServiceCleanup
cleanup)
throws ManifoldCFException;
/** End service activity.
Added:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java?rev=1545304&view=auto
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
(added)
+++
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
Mon Nov 25 14:41:36 2013
@@ -0,0 +1,50 @@
+/* $Id$ */
+
+/**
+* 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.manifoldcf.core.interfaces;
+
+
+/** The IServiceCleanup interface describes functionality needed to clean up
after
+* a service that has ended, as determined by an ILockManager instance. It is
always
+* throttled in a manner where only one thread in
+* the entire cluster will be cleaning up after any specific service.
+*/
+public interface IServiceCleanup
+{
+ public static final String _rcsid = "@(#)$Id$";
+
+ /** Clean up after the specified service. This method will block any
startup of the specified
+ * service for as long as it runs.
+ *@param serviceName is the name of the service.
+ */
+ public void cleanUpService(String serviceName)
+ throws ManifoldCFException;
+
+ /** Clean up after ALL services of the type on the cluster.
+ */
+ public void cleanUpAllServices()
+ throws ManifoldCFException;
+
+ /** Perform cluster initialization - that is, whatever is needed presuming
that the
+ * cluster has been down for an indeterminate period of time, but is
otherwise in a clean
+ * state.
+ */
+ public void clusterInit()
+ throws ManifoldCFException;
+
+}
Propchange:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/IServiceCleanup.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java
Mon Nov 25 14:41:36 2013
@@ -98,12 +98,14 @@ public class BaseLockManager implements
* called when the service shuts down. Some ILockManager implementations
require that this take place for
* proper management.
* If the transient registration already exists, it is treated as an error
and an exception will be thrown.
+ * If registration will succeed, then this method may call an appropriate
IServiceCleanup method to clean up either the
+ * current service, or all services on the cluster.
*@param serviceType is the type of service.
*@param serviceName is the name of the service to register.
- *@return true if this is the only active service of this type at this time.
+ *@param cleanup is called to clean up either the current service, or all
services of this type, if no other active service exists
*/
@Override
- public boolean registerServiceBeginServiceActivity(String serviceType,
String serviceName)
+ public void registerServiceBeginServiceActivity(String serviceType, String
serviceName, IServiceCleanup cleanup)
throws ManifoldCFException
{
enterWriteLock(serviceLock);
@@ -113,182 +115,183 @@ public class BaseLockManager implements
String serviceActiveFlag = makeActiveServiceFlagName(serviceType,
serviceName);
if (checkGlobalFlag(serviceActiveFlag))
throw new ManifoldCFException("Service '"+serviceName+"' of type
'"+serviceType+"' is already active");
- // First, register the service and find out how many such services are
active.
+
+ // First, see where we stand.
+ // We need to find out whether (a) our service is already registered;
(b) how many registered services there are;
+ // (c) whether there are other active services. But no changes will be
made at this time.
boolean foundService = false;
boolean foundActiveService = false;
+ String resourceName;
int i = 0;
while (true)
{
- String resourceName = buildServiceListEntry(serviceType, i);
+ resourceName = buildServiceListEntry(serviceType, i);
String x = readServiceName(resourceName);
if (x == null)
- {
- if (!foundService)
- {
- writeServiceName(resourceName, serviceName);
- try
- {
- setGlobalFlag(makeRegisteredServiceFlagName(serviceType,
serviceName));
- }
- catch (Throwable e)
- {
- writeServiceName(resourceName, null);
- if (e instanceof Error)
- throw (Error)e;
- if (e instanceof RuntimeException)
- throw (RuntimeException)e;
- if (e instanceof ManifoldCFException)
- throw (ManifoldCFException)e;
- else
- throw new RuntimeException("Unknown exception of type:
"+e.getClass().getName()+": "+e.getMessage(),e);
- }
- }
break;
- }
if (x.equals(serviceName))
foundService = true;
else if (checkGlobalFlag(makeActiveServiceFlagName(serviceType, x)))
foundActiveService = true;
i++;
}
- // Now, set the appropriate active flag
- setGlobalFlag(serviceActiveFlag);
- return !foundActiveService;
- }
- finally
- {
- leaveWriteLock(serviceLock);
- }
- }
-
- /** Un-register a service.
- * This operation cancels the permanent registration of the specified service.
- * If the service does not exist, this method will do nothing.
- *@param serviceType is the type of service.
- *@param serviceName is the name of the service to unregister.
- */
- @Override
- public void unregisterService(String serviceType, String serviceName)
- throws ManifoldCFException
- {
- enterWriteLock(serviceLock);
- try
- {
- // First, do an active check
- String serviceActiveFlag = makeActiveServiceFlagName(serviceType,
serviceName);
- if (checkGlobalFlag(serviceActiveFlag))
- throw new ManifoldCFException("Service '"+serviceName+"' of type
'"+serviceType+"' is still active; can't unregister");
- String serviceRegisteredFlag =
makeRegisteredServiceFlagName(serviceType, serviceName);
- clearGlobalFlag(serviceRegisteredFlag);
- int i = 0;
- String removalEntry = null;
- String lastEntry = null;
- String lastService = null;
- while (true)
+
+ // Call the appropriate cleanup. This will depend on what's actually
registered, and what's active.
+ // If there were no services registered at all when we started, then no
cleanup is needed, just cluster init.
+ // If this fails, we must revert to having our service not be registered
and not be active.
+ boolean unregisterAll = false;
+ if (cleanup != null)
{
- String resourceName = buildServiceListEntry(serviceType, i);
- String x = readServiceName(resourceName);
- if (x == null)
+ if (i == 0)
+ cleanup.clusterInit();
+ else if (foundService && foundActiveService)
+ cleanup.cleanUpService(serviceName);
+ else if (!foundActiveService)
{
- if (lastEntry != null)
- writeServiceName(lastEntry, null);
- try
- {
- if (removalEntry != null && !lastEntry.equals(removalEntry))
- writeServiceName(removalEntry, lastService);
- }
- catch (Throwable e)
- {
- writeServiceName(lastEntry, lastService);
- if (e instanceof Error)
- throw (Error)e;
- if (e instanceof RuntimeException)
- throw (RuntimeException)e;
- if (e instanceof ManifoldCFException)
- throw (ManifoldCFException)e;
- throw new RuntimeException("Unknown exception of type
"+e.getClass().getName()+": "+e.getMessage(),e);
- }
- break;
+ cleanup.cleanUpAllServices();
+ cleanup.clusterInit();
+ unregisterAll = true;
+ }
+ }
+
+ if (unregisterAll)
+ {
+ // Unregister all (since we did a global cleanup)
+ int k = i;
+ while (k > 0)
+ {
+ k--;
+ resourceName = buildServiceListEntry(serviceType, k);
+ String x = readServiceName(resourceName);
+ clearGlobalFlag(makeRegisteredServiceFlagName(serviceType, x));
+ writeServiceName(resourceName, null);
}
- lastEntry = resourceName;
- lastService = x;
- if (x.equals(serviceName))
- removalEntry = resourceName;
- i++;
}
+
+ // Now, register (if needed)
+ if (!foundService)
+ {
+ writeServiceName(resourceName, serviceName);
+ try
+ {
+ setGlobalFlag(makeRegisteredServiceFlagName(serviceType,
serviceName));
+ }
+ catch (Throwable e)
+ {
+ writeServiceName(resourceName, null);
+ if (e instanceof Error)
+ throw (Error)e;
+ if (e instanceof RuntimeException)
+ throw (RuntimeException)e;
+ if (e instanceof ManifoldCFException)
+ throw (ManifoldCFException)e;
+ else
+ throw new RuntimeException("Unknown exception of type:
"+e.getClass().getName()+": "+e.getMessage(),e);
+ }
+ }
+
+ // Last, set the appropriate active flag
+ setGlobalFlag(serviceActiveFlag);
}
finally
{
leaveWriteLock(serviceLock);
}
}
-
- /** List all registered services of a given type.
+
+ /** Count all active services of a given type.
*@param serviceType is the service type.
- *@return the service names.
+ *@return the count.
*/
@Override
- public String[] getRegisteredServices(String serviceType)
+ public int countActiveServices(String serviceType)
throws ManifoldCFException
{
enterWriteLock(serviceLock);
try
{
+ int count = 0;
int i = 0;
- List<String> services = new ArrayList<String>();
while (true)
{
String resourceName = buildServiceListEntry(serviceType, i);
String x = readServiceName(resourceName);
if (x == null)
break;
- services.add(x);
+ if (checkGlobalFlag(makeActiveServiceFlagName(serviceType, x)))
+ count++;
i++;
}
- String[] rval = new String[services.size()];
- i = 0;
- for (String x : services)
- {
- rval[i++] = x;
- }
- return rval;
+ return count;
}
finally
{
leaveWriteLock(serviceLock);
}
}
-
- /** List services that are registered but not active.
+
+ /** Clean up any inactive services found.
+ * Calling this method will invoke cleanup of one inactive service at a time.
+ * If there are no inactive services around, then false will be returned.
+ * Note that this method will block whatever service it finds from starting up
+ * for the time the cleanup is proceeding. At the end of the cleanup, if
+ * successful, the service will be atomically unregistered.
*@param serviceType is the service type.
- *@return the list of service names.
+ *@param cleanup is the object to call to clean up an inactive service.
+ *@return true if there were no cleanup operations necessary.
*/
@Override
- public String[] getInactiveServices(String serviceType)
+ public boolean cleanupInactiveService(String serviceType, IServiceCleanup
cleanup)
throws ManifoldCFException
{
enterWriteLock(serviceLock);
try
{
+ // We find ONE service that is registered but inactive, and clean up
after that one.
+ // Presumably the caller will lather, rinse, and repeat.
+ String serviceName;
+ String resourceName;
int i = 0;
- List<String> inactiveServices = new ArrayList<String>();
while (true)
{
- String resourceName = buildServiceListEntry(serviceType, i);
- String x = readServiceName(resourceName);
- if (x == null)
+ resourceName = buildServiceListEntry(serviceType, i);
+ serviceName = readServiceName(resourceName);
+ if (serviceName == null)
+ return true;
+ if (!checkGlobalFlag(makeActiveServiceFlagName(serviceType,
serviceName)))
break;
- if (!checkGlobalFlag(makeActiveServiceFlagName(serviceType, x)))
- inactiveServices.add(x);
i++;
}
- String[] rval = new String[inactiveServices.size()];
- i = 0;
- for (String x : inactiveServices)
+
+ // Found one, in serviceName, at position i
+ // Ideally, we should signal at this point that we're cleaning up after
it, and then leave
+ // the exclusive lock, so that other activity can take place. MHL
+ cleanup.cleanUpService(serviceName);
+
+ // Clean up the registration
+ String serviceRegisteredFlag =
makeRegisteredServiceFlagName(serviceType, serviceName);
+
+ // Find the end of the list
+ int k = i + 1;
+ String lastResourceName = null;
+ String lastServiceName = null;
+ while (true)
{
- rval[i++] = x;
+ String rName = buildServiceListEntry(serviceType, k);
+ String x = readServiceName(rName);
+ if (x == null)
+ break;
+ lastResourceName = rName;
+ lastServiceName = x;
+ k++;
}
- return rval;
+
+ // Rearrange the registration
+ clearGlobalFlag(serviceRegisteredFlag);
+ if (lastServiceName != null)
+ writeServiceName(resourceName, lastServiceName);
+ writeServiceName(lastResourceName, null);
+ return false;
}
finally
{
Modified:
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
URL:
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java?rev=1545304&r1=1545303&r2=1545304&view=diff
==============================================================================
---
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
(original)
+++
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
Mon Nov 25 14:41:36 2013
@@ -52,49 +52,45 @@ public class LockManager implements ILoc
* called when the service shuts down. Some ILockManager implementations
require that this take place for
* proper management.
* If the transient registration already exists, it is treated as an error
and an exception will be thrown.
+ * If registration will succeed, then this method may call an appropriate
IServiceCleanup method to clean up either the
+ * current service, or all services on the cluster.
*@param serviceType is the type of service.
*@param serviceName is the name of the service to register.
- *@return true if this is the only active service of this type at this time.
+ *@param cleanup is called to clean up either the current service, or all
services of this type, if no other active service exists
*/
@Override
- public boolean registerServiceBeginServiceActivity(String serviceType,
String serviceName)
+ public void registerServiceBeginServiceActivity(String serviceType, String
serviceName, IServiceCleanup cleanup)
throws ManifoldCFException
{
- return lockManager.registerServiceBeginServiceActivity(serviceType,
serviceName);
+ lockManager.registerServiceBeginServiceActivity(serviceType, serviceName,
cleanup);
}
- /** Un-register a service.
- * This operation cancels the permanent registration of the specified service.
- * If the service does not exist, this method will do nothing.
- *@param serviceType is the type of service.
- *@param serviceName is the name of the service to unregister.
- */
- @Override
- public void unregisterService(String serviceType, String serviceName)
- throws ManifoldCFException
- {
- lockManager.unregisterService(serviceType, serviceName);
- }
-
- /** List all registered services of a given type.
+ /** Clean up any inactive services found.
+ * Calling this method will invoke cleanup of one inactive service at a time.
+ * If there are no inactive services around, then false will be returned.
+ * Note that this method will block whatever service it finds from starting up
+ * for the time the cleanup is proceeding. At the end of the cleanup, if
+ * successful, the service will be atomically unregistered.
*@param serviceType is the service type.
- *@return the service names.
+ *@param cleanup is the object to call to clean up an inactive service.
+ *@return true if there were no cleanup operations necessary.
*/
@Override
- public String[] getRegisteredServices(String serviceType)
+ public boolean cleanupInactiveService(String serviceType, IServiceCleanup
cleanup)
throws ManifoldCFException
{
- return lockManager.getRegisteredServices(serviceType);
+ return lockManager.cleanupInactiveService(serviceType, cleanup);
}
-
- /** List services that are registered but not active.
+
+ /** Count all active services of a given type.
*@param serviceType is the service type.
- *@return the list of service names.
+ *@return the count.
*/
- public String[] getInactiveServices(String serviceType)
+ @Override
+ public int countActiveServices(String serviceType)
throws ManifoldCFException
{
- return lockManager.getInactiveServices(serviceType);
+ return lockManager.countActiveServices(serviceType);
}
/** End service activity.