Class ServiceControllerImpl<S>

    • Field Detail

      • ILLEGAL_CONTROLLER_STATE

        private static final java.lang.String ILLEGAL_CONTROLLER_STATE
        See Also:
        Constant Field Values
      • serviceValue

        private final Value<? extends Service<S>> serviceValue
        The service itself.
      • dependencies

        private final Dependency[] dependencies
        The dependencies of this service.
      • injections

        private final ValueInjection<?>[] injections
        The injections of this service.
      • outInjections

        private final ValueInjection<?>[] outInjections
        The out injections of this service.
      • primaryRegistration

        private final ServiceRegistrationImpl primaryRegistration
        The primary registration of this service.
      • aliasRegistrations

        private final ServiceRegistrationImpl[] aliasRegistrations
        The alias registrations of this service.
      • immediateUnavailableDependencies

        private final IdentityHashSet<ServiceName> immediateUnavailableDependencies
        The immediate unavailable dependencies of this service.
      • startException

        private StartException startException
        The start exception.
      • demandedByCount

        private int demandedByCount
        The number of registrations which place a demand-to-start on this instance. If this value is >0, propagate a demand up to all parent dependents. If this value is >0 and mode is ON_DEMAND, we should start.
      • unstartedDependencies

        private int unstartedDependencies
        The number of dependencies which are not yet started. This service cannot start until this count reaches zero.
      • stoppingDependencies

        private int stoppingDependencies
        Count for dependencies that are trying to stop. If this count is greater than zero then dependents will be notified that a stop is necessary.
      • runningDependents

        private int runningDependents
        The number of dependents that are currently running. The deployment will not execute the stop() method (and subsequently leave the ServiceController.State.STOPPING state) until all running dependents (and listeners) are stopped.
      • failCount

        private int failCount
        Count for failure notification. It indicates how many services have failed to start and are not recovered so far. This count monitors failures that happen when starting this service, and dependency related failures as well. When incremented from 0 to 1, it is time to notify dependents and listeners that a failure occurred. When decremented from 1 to 0, the dependents and listeners are notified that the affected services are retrying to start. Values larger than 1 are ignored to avoid multiple notifications.
      • transitiveUnavailableDepCount

        private int transitiveUnavailableDepCount
        Indicates if this service has one or more transitive dependencies that are not available. Count for notification of unavailable dependencies. Its value indicates how many transitive dependencies are unavailable. When incremented from 0 to 1, dependents are notified of the unavailable dependency unless immediateUnavailableDependencies is not empty. When decremented from 1 to 0, a notification that the unavailable dependencies are now available is sent to dependents, unless immediateUnavailableDependencies is not empty. Values larger than 1 are ignored to avoid multiple notifications.
      • dependenciesDemanded

        private boolean dependenciesDemanded
        Indicates whether dependencies have been demanded.
      • asyncTasks

        private int asyncTasks
        The number of asynchronous tasks that are currently running. This includes listeners, start/stop methods, outstanding asynchronous start/stops, and internal tasks.
      • lifecycleTime

        private volatile long lifecycleTime
        The system nanotime of the moment in which the last lifecycle change was initiated.
      • NO_DEPENDENTS

        private static final Dependent[] NO_DEPENDENTS
      • NO_STRINGS

        private static final java.lang.String[] NO_STRINGS
      • NO_NAMES

        private static final ServiceName[] NO_NAMES
    • Method Detail

      • addAsyncTasks

        void addAsyncTasks​(int size)
      • removeAsyncTask

        void removeAsyncTask()
      • startInstallation

        void startInstallation()
        Start this service installation, connecting it to its parent and dependencies. Also, set the instance in primary and alias registrations.

        All notifications from dependencies, parents, and registrations will be ignored until the installation is committed.

      • commitInstallation

        void commitInstallation​(ServiceController.Mode initialMode)
        Commit the service install, kicking off the mode set and listener execution.
        Parameters:
        initialMode - the initial service mode
      • rollbackInstallation

        void rollbackInstallation()
        Roll back the service install.
      • isInstallationCommitted

        boolean isInstallationCommitted()
        Return true only if this service controller installation is committed.
        Returns:
        true if this service controller installation is committed
      • shouldStart

        private boolean shouldStart()
        Determine whether a stopped controller should start.
        Returns:
        true if so
      • shouldStop

        private boolean shouldStop()
        Determine whether a running controller should stop.
        Returns:
        true if so
      • isStableRestState

        boolean isStableRestState()
        Returns true if controller is in rest state and no async tasks are running, false otherwise.
        Returns:
        true if stable rest state, false otherwise
      • updateStabilityState

        void updateStabilityState​(boolean leavingStableRestState)
      • getTransition

        private ServiceController.Transition getTransition()
        Identify the transition to take. Call under lock.
        Returns:
        the transition or null if none is needed at this time
      • transition

        void transition​(java.util.ArrayList<java.lang.Runnable> tasks)
        Run the locked portion of a transition. Call under lock.
        Parameters:
        tasks - the list to which async tasks should be appended
      • getListenerTasks

        private void getListenerTasks​(ServiceController.Transition transition,
                                      java.util.ArrayList<java.lang.Runnable> tasks)
      • doExecute

        void doExecute​(java.util.ArrayList<java.lang.Runnable> tasks)
      • setMode

        public void setMode​(ServiceController.Mode newMode)
        Description copied from interface: ServiceController
        Change the service controller's current mode. Might result in the service starting or stopping. The mode may only be changed if it was not already set to ServiceController.Mode.REMOVE. Calling this method with the controller's current mode has no effect and is always allowed.
        Specified by:
        setMode in interface ServiceController<S>
        Parameters:
        newMode - the new controller mode
      • internalSetMode

        private void internalSetMode​(ServiceController.Mode newMode,
                                     java.util.ArrayList<java.lang.Runnable> taskList)
      • immediateDependencyAvailable

        public void immediateDependencyAvailable​(ServiceName dependencyName)
        Description copied from interface: Dependent
        Notify this dependent that one of its immediate dependencies is available, i.e., it is installed and, if not started, should start shortly.

        This method must not be called under a lock.

        Specified by:
        immediateDependencyAvailable in interface Dependent
        Parameters:
        dependencyName - the name of the immediate dependency that is now available
      • immediateDependencyUnavailable

        public void immediateDependencyUnavailable​(ServiceName dependencyName)
        Description copied from interface: Dependent
        Notify this dependent that one of its immediate dependencies is unavailable.
        A dependency is unavailable when it is not installed or when it is in NEVER mode.

        This method must not be called under a lock.

        Specified by:
        immediateDependencyUnavailable in interface Dependent
        Parameters:
        dependencyName - the name of the immediate dependency that is now unavailable
      • propagateTransitiveUnavailability

        private void propagateTransitiveUnavailability()
      • propagateTransitiveAvailability

        private void propagateTransitiveAvailability()
      • transitiveDependencyAvailable

        public void transitiveDependencyAvailable()
        Description copied from interface: Dependent
        Notify this dependent that all unavailable transitive dependencies are now available (i.e., they are installed and will perform an attempt to start shortly).

        This method must not be called under a lock.

        Specified by:
        transitiveDependencyAvailable in interface Dependent
      • transitiveDependencyUnavailable

        public void transitiveDependencyUnavailable()
        Description copied from interface: Dependent
        Notify this dependent that one of its transitive dependencies is unavailable (either uninstalled, or in NEVER mode).

        New transitive dependencies that become unavailable after the notified one do not result in new dependencyUnavailable notifications, as the dependent will never receive two or more dependencyUnavailable calls in a row. A dependencyUnavailable notification is only invoked again to notify of newly found unavailable dependencies if all the previously unavailable dependencies have become available.

        This method must not be called under a lock.

        Specified by:
        transitiveDependencyUnavailable in interface Dependent
      • immediateDependencyUp

        public void immediateDependencyUp()
        Description copied from interface: Dependent
        Notify this dependent that one of its immediate dependencies entered UP state.

        This method must not be called under a lock.

        Specified by:
        immediateDependencyUp in interface Dependent
      • immediateDependencyDown

        public void immediateDependencyDown()
        Description copied from interface: Dependent
        Notify this dependent that one of its immediate dependencies is leaving the UP state.

        This method must not be called under a lock.

        Specified by:
        immediateDependencyDown in interface Dependent
      • dependencyFailed

        public void dependencyFailed()
        Description copied from interface: Dependent
        Notify this dependent that one of its dependencies (immediate or transitive) failed to start. This method is called after the dependency state transitions from STARTING to START_FAILED.

        Dependency failures that occur after the notified failure do not result in new dependencyFailed notifications, as the dependent will never receive two or more dependencyFailed calls in a row. A dependencyFailed notification is only invoked again to notify of new failures if the previous failures have been cleared.

        This method must not be called under a lock.

        Specified by:
        dependencyFailed in interface Dependent
      • dependencyFailureCleared

        public void dependencyFailureCleared()
        Description copied from interface: Dependent
        Notify this dependent that all dependency failures previously notified are now cleared. This method is called only after all affected dependencies left START_FAILED state.

        This method must not be called under a lock.

        Specified by:
        dependencyFailureCleared in interface Dependent
      • dependentStarted

        void dependentStarted()
      • dependentStopped

        void dependentStopped()
      • doDemandDependencies

        private void doDemandDependencies()
      • doUndemandDependencies

        private void doUndemandDependencies()
      • addDemand

        void addDemand()
      • addDemands

        void addDemands​(int demandedByCount)
      • removeDemand

        void removeDemand()
      • getValue

        public S getValue()
                   throws java.lang.IllegalStateException
        Description copied from interface: ServiceController
        Get the service value.
        Specified by:
        getValue in interface ServiceController<S>
        Specified by:
        getValue in interface Value<S>
        Returns:
        the service value
        Throws:
        java.lang.IllegalStateException - if the service is not available (i.e. it is not up)
      • awaitValue

        public S awaitValue()
                     throws java.lang.IllegalStateException,
                            java.lang.InterruptedException
        Description copied from interface: ServiceController
        Wait for a service to come up, and then return its value.
        Specified by:
        awaitValue in interface ServiceController<S>
        Returns:
        the service value
        Throws:
        java.lang.IllegalStateException - if the service is not available (i.e. it was removed or failed)
        java.lang.InterruptedException - if the wait operation was interrupted
      • awaitValue

        public S awaitValue​(long time,
                            java.util.concurrent.TimeUnit unit)
                     throws java.lang.IllegalStateException,
                            java.lang.InterruptedException,
                            java.util.concurrent.TimeoutException
        Description copied from interface: ServiceController
        Wait for a service to come up for a certain amount of time, and then return its value.
        Specified by:
        awaitValue in interface ServiceController<S>
        Parameters:
        time - the amount of time to wait
        unit - the unit of time to wait
        Returns:
        the service value
        Throws:
        java.lang.IllegalStateException - if the service is not available (i.e. it was removed or failed)
        java.lang.InterruptedException - if the wait operation was interrupted
        java.util.concurrent.TimeoutException
      • getService

        public Service<S> getService()
                              throws java.lang.IllegalStateException
        Description copied from interface: ServiceController
        Get the service.
        Specified by:
        getService in interface ServiceController<S>
        Returns:
        the service
        Throws:
        java.lang.IllegalStateException - if the service is not available (i.e. it is not up)
      • addListener

        public void addListener​(ServiceListener<? super S> listener)
        Description copied from interface: ServiceController
        Add a service listener. The listener's "listener added" callback will be invoked from the same thread that calls this method. Then, the method corresponding to the current service state is called.
        Specified by:
        addListener in interface ServiceController<S>
        Parameters:
        listener - the service listener
      • getStartException

        public StartException getStartException()
        Description copied from interface: ServiceController
        Get the reason why the last start failed.
        Specified by:
        getStartException in interface ServiceController<S>
        Returns:
        the last start exception, or null if the last start succeeded or the service has not yet started
      • compareAndSetMode

        public boolean compareAndSetMode​(ServiceController.Mode expectedMode,
                                         ServiceController.Mode newMode)
        Description copied from interface: ServiceController
        Compare the current mode against expected; if it matches, change it to newMode. The return value is true when the mode was matched and changed.
        Specified by:
        compareAndSetMode in interface ServiceController<S>
        Parameters:
        expectedMode - the expected mode
        newMode - the new mode
        Returns:
        true if the mode was changed
      • dumpServiceDetails

        java.lang.String dumpServiceDetails()
      • removeMonitorNoCallback

        void removeMonitorNoCallback​(StabilityMonitor stabilityMonitor)
      • getDependents

        private Dependent[][] getDependents()
        Returns a compiled array of all dependents of this service instance.
        Returns:
        an array of dependents, including children
      • getDependentsByDependencyName

        private java.util.Map<ServiceName,​Dependent[]> getDependentsByDependencyName()
        Returns a compiled map of all dependents of this service mapped by the dependency name. This map can be used when it is necessary to perform notifications to these dependents that require the name of the dependency issuing notification.
        The return result does not include children.
        Returns:
        an array of dependents, including children
      • doInject

        private static <T> void doInject​(ValueInjection<T> injection)
      • setTCCL

        private static java.lang.ClassLoader setTCCL​(java.lang.ClassLoader newTCCL)
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • writeProfileInfo

        private void writeProfileInfo​(char statusChar,
                                      long startNanos,
                                      long endNanos)