All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aspectran.core.service.AbstractServiceLifeCycle Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2025 The Aspectran Project
 *
 * Licensed 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 com.aspectran.core.service;

import com.aspectran.utils.Assert;
import com.aspectran.utils.ObjectUtils;
import com.aspectran.utils.annotation.jsr305.NonNull;
import com.aspectran.utils.annotation.jsr305.Nullable;
import com.aspectran.utils.logging.Logger;
import com.aspectran.utils.logging.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * The Class AbstractServiceLifeCycle.
 */
public abstract class AbstractServiceLifeCycle implements ServiceLifeCycle {

    private final Logger logger = LoggerFactory.getLogger(AbstractServiceLifeCycle.class);

    private final Object lock = new Object();

    private final List derivedServices = new ArrayList<>();

    private final CoreService rootService;

    private final CoreService parentService;

    private ServiceStateListener serviceStateListener;

    /** Flag that indicates whether this service is active */
    private volatile boolean active;

    public AbstractServiceLifeCycle(@Nullable CoreService parentService) {
        this.parentService = parentService;
        if (parentService != null) {
            this.rootService = parentService.getRootService();
            this.rootService.getServiceLifeCycle().joinDerivedService(this);
        } else {
            this.rootService = (CoreService)this;
        }
    }

    @Override
    public String getServiceName() {
        return ObjectUtils.simpleIdentityToString(this);
    }

    @Override
    @NonNull
    public CoreService getRootService() {
        return rootService;
    }

    @Override
    public CoreService getParentService() {
        return parentService;
    }

    @Override
    public boolean isRootService() {
        return (parentService == null);
    }

    @Override
    public boolean isOrphan() {
        return (parentService == null || parentService.getServiceLifeCycle().isActive());
    }

    @Override
    public void setServiceStateListener(ServiceStateListener serviceStateListener) {
        this.serviceStateListener = serviceStateListener;
    }

    @Override
    public void joinDerivedService(ServiceLifeCycle serviceLifeCycle) {
        derivedServices.add(serviceLifeCycle);
    }

    @Override
    public void withdrawDerivedService(@NonNull ServiceLifeCycle serviceLifeCycle) {
        Assert.state(serviceLifeCycle.isDerived(), "Not derived service: " + serviceLifeCycle);
        Assert.state(!serviceLifeCycle.isActive(), "Not yet stopped service: " + serviceLifeCycle);
        derivedServices.remove(serviceLifeCycle);
    }

    @Override
    public void leaveFromRootService() {
        if (isDerived()) {
            getRootService().getServiceLifeCycle().withdrawDerivedService(this);
        }
    }

    protected void clearDerivedServices() {
        derivedServices.clear();
    }

    protected Object getLock() {
        return lock;
    }

    protected abstract void doStart() throws Exception;

    protected abstract void doStop() throws Exception;

    @Override
    public void start() throws Exception {
        synchronized (lock) {
            Assert.state(!active, getServiceName() + " has already started");

            logger.info("Starting " + getServiceName());

            doStart();

            logger.info("Started " + getServiceName());

            for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                serviceLifeCycle.start();
            }

            if (serviceStateListener != null) {
                serviceStateListener.started();
            }

            active = true;
        }
    }

    @Override
    public void stop() {
        synchronized (lock) {
            if (!active) {
                if (logger.isDebugEnabled()) {
                    logger.debug(getServiceName() + " is not running, will do nothing");
                }
                return;
            }

            if (serviceStateListener != null) {
                try {
                    serviceStateListener.paused();
                    serviceStateListener.stopped();
                } catch (Exception e) {
                    logger.warn(e);
                }
            }

            for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                serviceLifeCycle.stop();
            }

            try {
                logger.info("Stopping " + getServiceName());

                doStop();

                logger.info("Stopped " + getServiceName());
            } catch (Exception e) {
                logger.error(getServiceName() + " did not stop normally", e);
            }

            active = false;
        }
    }

    @Override
    public void restart() throws Exception {
        synchronized (lock) {
            Assert.state(isRootService(), "Must be a root service to restart");
            Assert.state(active, getServiceName() + " is not yet started");

            logger.info("Restarting " + getServiceName());

            if (serviceStateListener != null) {
                serviceStateListener.paused();
            }

            for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                serviceLifeCycle.stop();
            }

            active = false;
            doStop();

            if (serviceStateListener != null) {
                try {
                    serviceStateListener.stopped();
                } catch (Exception e) {
                    logger.warn(e);
                }
            }

            doStart();
            active = true;

            logger.info("Restarted " + getServiceName());

            for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                serviceLifeCycle.start();
            }

            if (serviceStateListener != null) {
                serviceStateListener.started();
            }
        }
    }

    @Override
    public void restart(String message) throws Exception {
        restart();
    }

    @Override
    public void pause() throws Exception {
        synchronized (lock) {
            if (!active) {
                logger.warn(getServiceName() + " is not yet started");
                return;
            }

            if (!isDerived()) {
                for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                    serviceLifeCycle.pause();
                }
            }

            if (serviceStateListener != null) {
                serviceStateListener.paused();
            }

            logger.info("Pause " + getServiceName());
        }
    }

    @Override
    public void pause(long timeout) throws Exception {
        synchronized (lock) {
            if (!active) {
                logger.warn(getServiceName() + " is not yet started");
                return;
            }

            if (!isDerived()) {
                for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                    serviceLifeCycle.pause(timeout);
                }
            }

            if (serviceStateListener != null) {
                serviceStateListener.paused(timeout);
            }

            logger.info("Pause " + getServiceName() + ", resume after " + timeout + "ms");
        }
    }

    @Override
    public void resume() throws Exception {
        synchronized (lock) {
            if (!active) {
                logger.warn(getServiceName() + " is not yet started");
                return;
            }

            if (!isDerived()) {
                for (ServiceLifeCycle serviceLifeCycle : derivedServices) {
                    serviceLifeCycle.resume();
                }
            }

            if (serviceStateListener != null) {
                serviceStateListener.resumed();
            }

            logger.info("Resume " + getServiceName());
        }
    }

    @Override
    public boolean isActive() {
        return active;
    }

    @Override
    public boolean isBusy() {
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy