Author: kwright
Date: Thu Dec  5 18:13:27 2013
New Revision: 1548227

URL: http://svn.apache.org/r1548227
Log:
Add anonymous services

Modified:
    
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnectorpool/OutputConnectorPool.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
    
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java

Modified: 
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnectorpool/OutputConnectorPool.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnectorpool/OutputConnectorPool.java?rev=1548227&r1=1548226&r2=1548227&view=diff
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnectorpool/OutputConnectorPool.java
 (original)
+++ 
manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnectorpool/OutputConnectorPool.java
 Thu Dec  5 18:13:27 2013
@@ -35,8 +35,32 @@ public class OutputConnectorPool impleme
   /** Local connector pool */
   protected final static LocalPool localPool = new LocalPool();
 
-  // This implementation is a place-holder for the real one, which will likely 
fold in the pooling code
-  // as we strip it out of OutputConnectorFactory.
+  // How global connector allocation works:
+  // (1) There is a lock-manager "service" associated with this connector 
pool.  This allows us to clean
+  // up after local pools that have died without being released.  There's one 
service instance per local pool,
+  // and thus one service instance per JVM.  NOTE WELL: This means that we 
need distinct process id's
+  // for non-agent services as well!!  How do we do that??
+  // A: -D always overrides processID, but in addition there's a default 
describing the kind of process it is,
+  // e.g. "" for agents, "AUTH" for authority service, "API" for api service, 
"UI" for crawler UI, "CL" for
+  // command line.
+  // Next question; how does the process ID get set for these?
+  // A: Good question...
+  // Alternative: SINCE the pools are in-memory-only and static, maybe we can 
just mint a unique ID for
+  // each pool on each instantiation.
+  // Problem: Guaranteeing uniqueness
+  // Solution: Zookeeper sequential nodes will do that for us, but is there a 
local/file equivalent?  Must be, but lock manager
+  // needs extension, clearly.  But given that, it should be possible to have 
a globally-unique, transient "pool ID".
+  // The transient globally-unique ID seems like the best solution.
+  // (2) Each local pool knows how many connector instances of each type 
(keyed by class name and config info) there
+  // are.
+  // (3) Each local pool/connector instance type has a local authorization 
count.  This is the amount it's
+  // allowed to actually keep.  If the pool has more connectors of a type than 
the local authorization count permits,
+  // then every connector release operation will destroy the released 
connector until the local authorization count
+  // is met.
+  // (4) Each local pool/connector instance type needs a global variable 
describing how many CURRENT instances
+  // the local pool has allocated.  This is a transient value which should 
automatically go to zero if the service becomes inactive.
+  // The lock manager will need to be extended in order to provide this 
functionality - essentially, transient service-associated data.
+  // There also needs to be a fast way to sum the data for all active services 
(but that does not need to be a lock-manager primitive)
 
   /** Thread context */
   protected final IThreadContext threadContext;

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=1548227&r1=1548226&r2=1548227&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
 Thu Dec  5 18:13:27 2013
@@ -44,10 +44,13 @@ public interface ILockManager
   * 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.
-  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists
+  *@param serviceName is the name of the service to register.  If null is 
passed, a transient unique service name will be
+  *    created, and will be returned to the caller.
+  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists.
+  *    May be null.  Local service cleanup is never called if the serviceName 
argument is null.
+  *@return the actual service name.
   */
-  public void registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
+  public String registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
     throws ManifoldCFException;
   
   /** Count all active services of a given type.

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=1548227&r1=1548226&r2=1548227&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
 Thu Dec  5 18:13:27 2013
@@ -87,7 +87,11 @@ public class BaseLockManager implements 
   protected final static String servicePrefix = "_SERVICE_";
   /** A flag prefix, followed by the service type, and then followed by "_" 
and the service name */
   protected final static String activePrefix = "_ACTIVE_";
-
+  /** Anonymous service name prefix, to be followed by an integer */
+  protected final static String anonymousServiceNamePrefix = "_ANON_";
+  /** Anonymous global variable name prefix, to be followed by the service 
type */
+  protected final static String anonymousServiceTypeCounter = 
"_SERVICECOUNTER_";
+  
   /** Register a service and begin service activity.
   * This atomic operation creates a permanent registration entry for a service.
   * If the permanent registration entry already exists, this method will not 
create it or
@@ -99,16 +103,22 @@ public class BaseLockManager implements 
   * 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.
-  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists
+  *@param serviceName is the name of the service to register.  If null is 
passed, a transient unique service name will be
+  *    created, and will be returned to the caller.
+  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists.
+  *    May be null.  Local service cleanup is never called if the serviceName 
argument is null.
+  *@return the actual service name.
   */
   @Override
-  public void registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
+  public String registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
     throws ManifoldCFException
   {
     enterWriteLock(serviceLock);
     try
     {
+      if (serviceName == null)
+        serviceName = constructUniqueServiceName(serviceType);
+      
       // First, do an active check
       String serviceActiveFlag = makeActiveServiceFlagName(serviceType, 
serviceName);
       if (checkGlobalFlag(serviceActiveFlag))
@@ -197,6 +207,7 @@ public class BaseLockManager implements 
 
       // Last, set the appropriate active flag
       setGlobalFlag(serviceActiveFlag);
+      return serviceName;
     }
     finally
     {
@@ -235,6 +246,51 @@ public class BaseLockManager implements 
     }
   }
 
+  /** Construct a unique service name given the service type.
+  */
+  protected String constructUniqueServiceName(String serviceType)
+    throws ManifoldCFException
+  {
+    String serviceCounterName = makeServiceCounterName(serviceType);
+    int serviceUID = readServiceCounter(serviceCounterName);
+    writeServiceCounter(serviceCounterName,serviceUID+1);
+    return anonymousServiceNamePrefix + serviceUID;
+  }
+  
+  /** Make the service counter name for a service type.
+  */
+  protected static String makeServiceCounterName(String serviceType)
+  {
+    return anonymousServiceTypeCounter + serviceType;
+  }
+  
+  /** Read service counter.
+  */
+  protected int readServiceCounter(String serviceCounterName)
+    throws ManifoldCFException
+  {
+    byte[] serviceCounterData = readData(serviceCounterName);
+    if (serviceCounterData == null || serviceCounterData.length != 4)
+      return 0;
+    return ((int)serviceCounterData[0]) & 0xff +
+      (((int)serviceCounterData[1]) << 8) & 0xff00 +
+      (((int)serviceCounterData[2]) << 16) & 0xff0000 +
+      (((int)serviceCounterData[3]) << 24) & 0xff000000;
+  }
+  
+  /** Write service counter.
+  */
+  protected void writeServiceCounter(String serviceCounterName, int counter)
+    throws ManifoldCFException
+  {
+    byte[] serviceCounterData = new byte[4];
+    serviceCounterData[0] = (byte)(counter & 0xff);
+    serviceCounterData[1] = (byte)((counter >> 8) & 0xff);
+    serviceCounterData[2] = (byte)((counter >> 16) & 0xff);
+    serviceCounterData[3] = (byte)((counter >> 24) & 0xff);
+    writeData(serviceCounterName,serviceCounterData);
+  }
+  
   /** 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.

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=1548227&r1=1548226&r2=1548227&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
 Thu Dec  5 18:13:27 2013
@@ -55,14 +55,17 @@ public class LockManager implements ILoc
   * 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.
-  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists
+  *@param serviceName is the name of the service to register.  If null is 
passed, a transient unique service name will be
+  *    created, and will be returned to the caller.
+  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists.
+  *    May be null.  Local service cleanup is never called if the serviceName 
argument is null.
+  *@return the actual service name.
   */
   @Override
-  public void registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
+  public String registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
     throws ManifoldCFException
   {
-    lockManager.registerServiceBeginServiceActivity(serviceType, serviceName, 
cleanup);
+    return lockManager.registerServiceBeginServiceActivity(serviceType, 
serviceName, cleanup);
   }
   
   /** Clean up any inactive services found.

Modified: 
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java?rev=1548227&r1=1548226&r2=1548227&view=diff
==============================================================================
--- 
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java
 (original)
+++ 
manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZooKeeperLockManager.java
 Thu Dec  5 18:13:27 2013
@@ -44,6 +44,11 @@ public class ZooKeeperLockManager extend
   private final static String SERVICETYPE_ACTIVE_PATH_PREFIX = 
"/org.apache.manifoldcf.serviceactive-";
   private final static String SERVICETYPE_REGISTER_PATH_PREFIX = 
"/org.apache.manifoldcf.service-";
   
+  /** Anonymous service name prefix, to be followed by an integer */
+  protected final static String anonymousServiceNamePrefix = "_ANON_";
+  /** Anonymous global variable name prefix, to be followed by the service 
type */
+  protected final static String anonymousServiceTypeCounter = 
"_SERVICECOUNTER_";
+
   // ZooKeeper connection pool
   protected static Integer connectionPoolLock = new Integer(0);
   protected static ZooKeeperConnectionPool pool = null;
@@ -100,11 +105,14 @@ public class ZooKeeperLockManager extend
   * 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.
-  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists
+  *@param serviceName is the name of the service to register.  If null is 
passed, a transient unique service name will be
+  *    created, and will be returned to the caller.
+  *@param cleanup is called to clean up either the current service, or all 
services of this type, if no other active service exists.
+  *    May be null.  Local service cleanup is never called if the serviceName 
argument is null.
+  *@return the actual service name.
   */
   @Override
-  public void registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
+  public String registerServiceBeginServiceActivity(String serviceType, String 
serviceName, IServiceCleanup cleanup)
     throws ManifoldCFException
   {
     try
@@ -115,6 +123,9 @@ public class ZooKeeperLockManager extend
         enterServiceRegistryLock(connection, serviceType);
         try
         {
+          if (serviceName == null)
+            serviceName = constructUniqueServiceName(serviceType);
+
           String activePath = buildServiceTypeActivePath(serviceType, 
serviceName);
           if (connection.checkNodeExists(activePath))
             throw new ManifoldCFException("Service '"+serviceName+"' of type 
'"+serviceType+"' is already active");
@@ -175,6 +186,7 @@ public class ZooKeeperLockManager extend
           
           // Last, set the appropriate active flag
           connection.createNode(activePath);
+          return serviceName;
         }
         finally
         {
@@ -390,6 +402,51 @@ public class ZooKeeperLockManager extend
     connection.releaseLock();
   }
   
+  /** Construct a unique service name given the service type.
+  */
+  protected String constructUniqueServiceName(String serviceType)
+    throws ManifoldCFException
+  {
+    String serviceCounterName = makeServiceCounterName(serviceType);
+    int serviceUID = readServiceCounter(serviceCounterName);
+    writeServiceCounter(serviceCounterName,serviceUID+1);
+    return anonymousServiceNamePrefix + serviceUID;
+  }
+  
+  /** Make the service counter name for a service type.
+  */
+  protected static String makeServiceCounterName(String serviceType)
+  {
+    return anonymousServiceTypeCounter + serviceType;
+  }
+  
+  /** Read service counter.
+  */
+  protected int readServiceCounter(String serviceCounterName)
+    throws ManifoldCFException
+  {
+    byte[] serviceCounterData = readData(serviceCounterName);
+    if (serviceCounterData == null || serviceCounterData.length != 4)
+      return 0;
+    return ((int)serviceCounterData[0]) & 0xff +
+      (((int)serviceCounterData[1]) << 8) & 0xff00 +
+      (((int)serviceCounterData[2]) << 16) & 0xff0000 +
+      (((int)serviceCounterData[3]) << 24) & 0xff000000;
+  }
+  
+  /** Write service counter.
+  */
+  protected void writeServiceCounter(String serviceCounterName, int counter)
+    throws ManifoldCFException
+  {
+    byte[] serviceCounterData = new byte[4];
+    serviceCounterData[0] = (byte)(counter & 0xff);
+    serviceCounterData[1] = (byte)((counter >> 8) & 0xff);
+    serviceCounterData[2] = (byte)((counter >> 16) & 0xff);
+    serviceCounterData[3] = (byte)((counter >> 24) & 0xff);
+    writeData(serviceCounterName,serviceCounterData);
+  }
+
   /** Build a zk path for the lock for a specific service type.
   */
   protected static String buildServiceTypeLockPath(String serviceType)


Reply via email to