Class ZooKeeperLockManager

  • All Implemented Interfaces:
    ILockManager

    public class ZooKeeperLockManager
    extends BaseLockManager
    implements ILockManager
    The lock manager manages locks across all threads and JVMs and cluster members, using Zookeeper. There should be no more than ONE instance of this class per thread!!! The factory should enforce this.
    • Field Detail

      • zookeeperConnectStringParameter

        protected static final java.lang.String zookeeperConnectStringParameter
        See Also:
        Constant Field Values
      • zookeeperSessionTimeoutParameter

        protected static final java.lang.String zookeeperSessionTimeoutParameter
        See Also:
        Constant Field Values
      • anonymousServiceNamePrefix

        protected static final java.lang.String anonymousServiceNamePrefix
        Anonymous service name prefix, to be followed by an integer
        See Also:
        Constant Field Values
      • connectionPoolLock

        protected static java.lang.Integer connectionPoolLock
      • zookeeperPoolLocker

        protected static java.lang.Integer zookeeperPoolLocker
      • myZooKeeperLocks

        protected static LockPool myZooKeeperLocks
      • ephemeralPoolLocker

        protected static java.lang.Integer ephemeralPoolLocker
    • Method Detail

      • registerServiceBeginServiceActivity

        public java.lang.String registerServiceBeginServiceActivity​(java.lang.String serviceType,
                                                                    java.lang.String serviceName,
                                                                    IServiceCleanup cleanup)
                                                             throws ManifoldCFException
        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 treat it as an error. This operation also enters the "active" zone for the service. The "active" zone will remain in force until it is canceled, or until the process is interrupted. Ideally, the corresponding endServiceActivity method will be 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.
        Specified by:
        registerServiceBeginServiceActivity in interface ILockManager
        Overrides:
        registerServiceBeginServiceActivity in class BaseLockManager
        Parameters:
        serviceType - is the type of service.
        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.
        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.
        Returns:
        the actual service name.
        Throws:
        ManifoldCFException
      • registerServiceBeginServiceActivity

        public java.lang.String registerServiceBeginServiceActivity​(java.lang.String serviceType,
                                                                    java.lang.String serviceName,
                                                                    byte[] initialData,
                                                                    IServiceCleanup cleanup)
                                                             throws ManifoldCFException
        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 treat it as an error. This operation also enters the "active" zone for the service. The "active" zone will remain in force until it is canceled, or until the process is interrupted. Ideally, the corresponding endServiceActivity method will be 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.
        Specified by:
        registerServiceBeginServiceActivity in interface ILockManager
        Overrides:
        registerServiceBeginServiceActivity in class BaseLockManager
        Parameters:
        serviceType - is the type of service.
        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.
        initialData - is the initial service data for this service.
        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.
        Returns:
        the actual service name.
        Throws:
        ManifoldCFException
      • updateServiceData

        public void updateServiceData​(java.lang.String serviceType,
                                      java.lang.String serviceName,
                                      byte[] serviceData)
                               throws ManifoldCFException
        Set service data for a service.
        Specified by:
        updateServiceData in interface ILockManager
        Overrides:
        updateServiceData in class BaseLockManager
        Parameters:
        serviceType - is the type of service.
        serviceName - is the name of the service.
        serviceData - is the data to update to (may be null). This updates the service's transient data (or deletes it). If the service is not active, an exception is thrown.
        Throws:
        ManifoldCFException
      • cleanupInactiveService

        public boolean cleanupInactiveService​(java.lang.String serviceType,
                                              IServiceCleanup cleanup)
                                       throws ManifoldCFException
        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.
        Specified by:
        cleanupInactiveService in interface ILockManager
        Overrides:
        cleanupInactiveService in class BaseLockManager
        Parameters:
        serviceType - is the service type.
        cleanup - is the object to call to clean up an inactive service.
        Returns:
        true if there were no cleanup operations necessary.
        Throws:
        ManifoldCFException
      • endServiceActivity

        public void endServiceActivity​(java.lang.String serviceType,
                                       java.lang.String serviceName)
                                throws ManifoldCFException
        End service activity. This operation exits the "active" zone for the service. This must take place using the same ILockManager object that was used to registerServiceBeginServiceActivity() - which implies that it is the same thread.
        Specified by:
        endServiceActivity in interface ILockManager
        Overrides:
        endServiceActivity in class BaseLockManager
        Parameters:
        serviceType - is the type of service.
        serviceName - is the name of the service to exit.
        Throws:
        ManifoldCFException
      • checkServiceActive

        public boolean checkServiceActive​(java.lang.String serviceType,
                                          java.lang.String serviceName)
                                   throws ManifoldCFException
        Check whether a service is active or not. This operation returns true if the specified service is considered active at the moment. Once a service is not active anymore, it can only return to activity by calling beginServiceActivity() once more.
        Specified by:
        checkServiceActive in interface ILockManager
        Overrides:
        checkServiceActive in class BaseLockManager
        Parameters:
        serviceType - is the type of service.
        serviceName - is the name of the service to check on.
        Returns:
        true if the service is considered active.
        Throws:
        ManifoldCFException
      • enterServiceRegistryReadLock

        protected void enterServiceRegistryReadLock​(ZooKeeperConnection connection,
                                                    java.lang.String serviceType)
                                             throws ManifoldCFException,
                                                    java.lang.InterruptedException
        Enter service registry read lock
        Throws:
        ManifoldCFException
        java.lang.InterruptedException
      • enterServiceRegistryWriteLock

        protected void enterServiceRegistryWriteLock​(ZooKeeperConnection connection,
                                                     java.lang.String serviceType)
                                              throws ManifoldCFException,
                                                     java.lang.InterruptedException
        Enter service registry write lock
        Throws:
        ManifoldCFException
        java.lang.InterruptedException
      • constructUniqueServiceName

        protected java.lang.String constructUniqueServiceName​(ZooKeeperConnection connection,
                                                              java.lang.String serviceType)
                                                       throws ManifoldCFException,
                                                              java.lang.InterruptedException
        Construct a unique service name given the service type.
        Throws:
        ManifoldCFException
        java.lang.InterruptedException
      • makeServiceCounterName

        protected static java.lang.String makeServiceCounterName​(java.lang.String serviceType)
        Make the service counter name for a service type.
      • writeServiceCounter

        protected void writeServiceCounter​(ZooKeeperConnection connection,
                                           java.lang.String serviceCounterName,
                                           int counter)
                                    throws ManifoldCFException,
                                           java.lang.InterruptedException
        Write service counter.
        Throws:
        ManifoldCFException
        java.lang.InterruptedException
      • buildServiceTypeLockPath

        protected static java.lang.String buildServiceTypeLockPath​(java.lang.String serviceType)
        Build a zk path for the lock for a specific service type.
      • buildServiceTypeActivePath

        protected static java.lang.String buildServiceTypeActivePath​(java.lang.String serviceType,
                                                                     java.lang.String encodedServiceName)
        Build a zk path for the active node for a specific service of a specific type.
      • buildServiceTypeRegistrationPath

        protected static java.lang.String buildServiceTypeRegistrationPath​(java.lang.String serviceType)
        Build a zk path for the registration node for a specific service type.
      • setSharedConfiguration

        public void setSharedConfiguration​(java.io.InputStream configurationInputStream)
                                    throws ManifoldCFException
        Write shared configuration. Caller closes the input stream.
        Throws:
        ManifoldCFException
      • readData

        public byte[] readData​(java.lang.String resourceName)
                        throws ManifoldCFException
        Read data from a shared data resource. Use this method to read any existing data, or get a null back if there is no such resource. Note well that this is not necessarily an atomic operation, and it must thus be protected by a lock.
        Specified by:
        readData in interface ILockManager
        Overrides:
        readData in class BaseLockManager
        Parameters:
        resourceName - is the global name of the resource.
        Returns:
        a byte array containing the data, or null.
        Throws:
        ManifoldCFException
      • writeData

        public void writeData​(java.lang.String resourceName,
                              byte[] data)
                       throws ManifoldCFException
        Write data to a shared data resource. Use this method to write a body of data into a shared resource. Note well that this is not necessarily an atomic operation, and it must thus be protected by a lock.
        Specified by:
        writeData in interface ILockManager
        Overrides:
        writeData in class BaseLockManager
        Parameters:
        resourceName - is the global name of the resource.
        data - is the byte array containing the data. Pass null if you want to delete the resource completely.
        Throws:
        ManifoldCFException
      • main

        public static void main​(java.lang.String[] argv)