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

com.aspectran.core.component.session.HouseKeeper Maven / Gradle / Ivy

There is a newer version: 8.1.5
Show newest version
/*
 * Copyright (c) 2008-2023 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.component.session;

import com.aspectran.core.util.ToStringBuilder;
import com.aspectran.core.util.lifecycle.AbstractLifeCycle;
import com.aspectran.core.util.logging.Logger;
import com.aspectran.core.util.logging.LoggerFactory;
import com.aspectran.core.util.thread.AutoLock;
import com.aspectran.core.util.thread.Scheduler;

import java.util.concurrent.TimeUnit;

/**
 * The housekeeper for session scavenging.
 * There is 1 session HouseKeeper per SessionManager instance.
 */
public class HouseKeeper extends AbstractLifeCycle {

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

    public static final long DEFAULT_SCAVENGING_INTERVAL_MS = 1000L * 60 * 10;

    private final AutoLock lock = new AutoLock();

    private final SessionHandler sessionHandler;

    private final Scheduler scheduler;

    private Scheduler.Task task; // scavenge task

    private Runner runner;

    /** 10 minute default */
    private long scavengingInterval = DEFAULT_SCAVENGING_INTERVAL_MS;

    /**
     * @param sessionHandler SessionHandler associated with this scavenger
     */
    public HouseKeeper(SessionHandler sessionHandler) {
        this.sessionHandler = sessionHandler;
        this.scheduler = sessionHandler.getScheduler();
    }

    /**
     * Get the period between scavenge cycles.
     * @return the interval (in seconds)
     */
    public int getScavengingInterval() {
        return (int)(scavengingInterval / 1000L);
    }

    /**
     * Set the period between scavenge cycles.
     * @param intervalInSecs the interval (in seconds)
     */
    public void setScavengingInterval(int intervalInSecs) {
        try (AutoLock ignored = lock.lock()) {
            if (isStarted() || isStarting()) {
                if (intervalInSecs <= 0) {
                    scavengingInterval = 0L;
                    logger.info("Scavenging disabled");
                    stopScavenging();
                } else {
                    if (intervalInSecs < 10) {
                        logger.warn("Short interval of " + intervalInSecs + " secs for session scavenging");
                    }
                    scavengingInterval = intervalInSecs * 1000L;
                    if (isStarting() || isStarted()) {
                        startScavenging();
                    }
                }
            } else {
                scavengingInterval = intervalInSecs * 1000L;
            }
        }
    }

    /**
     * If scavenging is not scheduled, schedule it.
     */
    protected void startScavenging() {
        try (AutoLock ignored = lock.lock()) {
            // cancel any previous task
            if (task != null) {
                task.cancel();
            }
            if (runner == null) {
                runner = new Runner();
            }
            logger.info(sessionHandler.getComponentName() + " Scavenging every " + scavengingInterval + " ms");
            task = scheduler.schedule(runner, scavengingInterval, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * If scavenging is scheduled, stop it.
     */
    protected void stopScavenging() {
        try (AutoLock ignored = lock.lock()) {
            if (task != null) {
                task.cancel();
                logger.info(sessionHandler.getComponentName() + " Stopped scavenging");
            }
            task = null;
            runner = null;
        }
    }

    /**
     * Periodically do session housekeeping.
     */
    private void scavenge() {
        // don't attempt to scavenge if we are shutting down
        if (isStopping() || isStopped()) {
            return;
        }
        try {
            sessionHandler.scavenge();
        } catch (Exception e) {
            logger.warn(e);
        }
    }

    @Override
    protected void doStart() throws Exception {
        setScavengingInterval(getScavengingInterval());
        super.doStart();
    }

    @Override
    protected void doStop() throws Exception {
        stopScavenging();
        super.doStop();
    }

    @Override
    public String toString() {
        ToStringBuilder tsb = new ToStringBuilder(super.toString());
        tsb.append("scavengingInterval", scavengingInterval);
        return tsb.toString();
    }

    /**
     * Runner
     */
    private class Runner implements Runnable {

        @Override
        public void run() {
            try {
                scavenge();
            } finally {
                try (AutoLock ignored = lock.lock()) {
                    if (scheduler != null && scheduler.isRunning()) {
                        task = scheduler.schedule(this, scavengingInterval, TimeUnit.MILLISECONDS);
                    }
                }
            }
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy