![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.jasperreports.chrome.ChromeInstanceRepository Maven / Gradle / Ivy
The newest version!
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2023 Cloud Software Group, Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.chrome;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Lucian Chirita ([email protected])
*/
public class ChromeInstanceRepository
{
private static final Log log = LogFactory.getLog(ChromeInstanceRepository.class);
private static final ChromeInstanceRepository INSTANCE = new ChromeInstanceRepository();
public static ChromeInstanceRepository instance()
{
return INSTANCE;
}
private final Map instances;
private final ScheduledExecutorService timeoutExecutor;
protected ChromeInstanceRepository()
{
this.instances = new HashMap<>();
this.timeoutExecutor = Executors.newScheduledThreadPool(1, runnable ->
{
Thread thread = new Thread(runnable);
thread.setName("Chrome timeout");
thread.setDaemon(true);
return thread;
});
}
public ChromeInstanceHandle getChromeInstanceHandle(LaunchConfiguration configuration)
{
ChromeInstance chromeInstance = instance(configuration);
return chromeInstance;
}
protected ChromeInstance instance(LaunchConfiguration configuration)
{
synchronized (instances)
{
ChromeInstance instance = instances.get(configuration);
if (instance != null && !instance.isAlive())
{
log.warn("Chrome instance " + instance.getId() + " not available");
instance = null;
}
if (instance == null)
{
instance = new ChromeInstance(configuration);
instance.start();//TODO do this without holding the lock
scheduleTimeoutChecks(configuration, instance);
instances.put(configuration, instance);
}
return instance;
}
}
protected void scheduleTimeoutChecks(LaunchConfiguration configuration, ChromeInstance chromeInstance)
{
long idleTimeout = configuration.getIdleTimeout();
if (idleTimeout > 0)
{
scheduleIdleTimeoutCheck(configuration, chromeInstance, idleTimeout, idleTimeout);
}
long liveTimeout = configuration.getLiveTimeout();
if (liveTimeout > 0)
{
scheduleLiveTimeoutCheck(configuration, chromeInstance, liveTimeout);
}
}
protected void scheduleIdleTimeoutCheck(LaunchConfiguration configuration, ChromeInstance chromeInstance,
long idleTimeout, long delay)
{
if (log.isDebugEnabled())
{
log.debug("schedule chrome instance " + chromeInstance.getId() + " idle timeout check after " + delay);
}
WeakReference instanceReference = new WeakReference<>(chromeInstance);
timeoutExecutor.schedule(() ->
{
checkIdle(configuration, instanceReference, idleTimeout);
}, delay, TimeUnit.MILLISECONDS);
}
protected void checkIdle(LaunchConfiguration configuration, WeakReference instanceReference,
long idleTimeout)
{
ChromeInstance instance = instanceReference.get();
if (instance == null)
{
if (log.isDebugEnabled())
{
log.debug("cleared chrome instance reference on idle check");
}
return;
}
if (log.isDebugEnabled())
{
log.debug("checking idle timeout for chrome instance " + instance.getId());
}
boolean toClose;
synchronized (instances)
{
long now = System.currentTimeMillis();
ChromeInstanceState state = instance.getState();
if (state.isClosed())
{
log.debug("chrome instance " + instance.getId() + " already closed");
toClose = false;
}
else
{
toClose = state.getUseCount() == 0 && state.getUseTimestamp() + idleTimeout <= now;
if (toClose)
{
removeCachedInstance(configuration, instance);
}
else
{
//reschedule check at lastUsed + idleTimeout
scheduleIdleTimeoutCheck(configuration, instance, idleTimeout,
state.getUseCount() == 0 ? (state.getUseTimestamp() + idleTimeout - now) : idleTimeout);
}
}
}
if (toClose)
{
if (log.isDebugEnabled())
{
log.debug("chrome instance " + instance.getId() + " exceeded idle timeout");
}
instance.close();
}
}
protected void scheduleLiveTimeoutCheck(LaunchConfiguration configuration, ChromeInstance chromeInstance,
long liveTimeout)
{
if (log.isDebugEnabled())
{
log.debug("schedule chrome instance " + chromeInstance.getId() + " timeout after " + liveTimeout);
}
WeakReference instanceReference = new WeakReference<>(chromeInstance);
timeoutExecutor.schedule(() ->
{
closeInstance(configuration, instanceReference);
}, liveTimeout, TimeUnit.MILLISECONDS);
}
protected void closeInstance(LaunchConfiguration configuration, WeakReference instanceReference)
{
ChromeInstance instance = instanceReference.get();
if (instance == null)
{
if (log.isDebugEnabled())
{
log.debug("cleared chrome instance reference on close");
}
return;
}
if (log.isDebugEnabled())
{
log.debug("live timeout for chrome instance " + instance.getId());
}
boolean toClose;
synchronized (instances)
{
ChromeInstanceState state = instance.getState();
toClose = !state.isClosed();
if (toClose)
{
removeCachedInstance(configuration, instance);
}
else
{
if (log.isDebugEnabled())
{
log.debug("chrome instance " + instance.getId() + " already closed");
}
}
}
if (toClose)
{
instance.close();
}
}
protected void removeCachedInstance(LaunchConfiguration configuration, ChromeInstance chromeInstance)
{
ChromeInstance cachedInstance = instances.get(configuration);
if (cachedInstance == chromeInstance)//this should always be the case
{
instances.remove(configuration);
}
else
{
//should not happen
if (log.isDebugEnabled())
{
log.debug("found different cached chrome instance "
+ (cachedInstance == null ? "null" : cachedInstance.getId()));
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy