NIHVIVO-719 More refactoring to shut down the thread properly.
This commit is contained in:
parent
285400f3df
commit
c8278af94d
1 changed files with 54 additions and 62 deletions
|
@ -9,6 +9,7 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
@ -37,6 +38,7 @@ public class VClassGroupCache{
|
||||||
private static final Log log = LogFactory.getLog(VClassGroupCache.class);
|
private static final Log log = LogFactory.getLog(VClassGroupCache.class);
|
||||||
|
|
||||||
private static final String ATTRIBUTE_NAME = "VClassGroupCache";
|
private static final String ATTRIBUTE_NAME = "VClassGroupCache";
|
||||||
|
private static final String REBUILD_EVERY_PORTAL = "Rebuild every portal.";
|
||||||
|
|
||||||
private static final boolean ORDER_BY_DISPLAYRANK = true;
|
private static final boolean ORDER_BY_DISPLAYRANK = true;
|
||||||
private static final boolean INCLUDE_UNINSTANTIATED = true;
|
private static final boolean INCLUDE_UNINSTANTIATED = true;
|
||||||
|
@ -49,7 +51,7 @@ public class VClassGroupCache{
|
||||||
return (VClassGroupCache) sc.getAttribute(ATTRIBUTE_NAME);
|
return (VClassGroupCache) sc.getAttribute(ATTRIBUTE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the cache of VClassGroups. It is a portal id to list of VClassGroups */
|
/** This is the cache of VClassGroups. It is a portal id to list of VClassGroups */
|
||||||
private final ConcurrentHashMap<Integer, List<VClassGroup>> _groupListMap;
|
private final ConcurrentHashMap<Integer, List<VClassGroup>> _groupListMap;
|
||||||
|
|
||||||
private final ConcurrentLinkedQueue<String> _rebuildQueue;
|
private final ConcurrentLinkedQueue<String> _rebuildQueue;
|
||||||
|
@ -74,8 +76,8 @@ public class VClassGroupCache{
|
||||||
_cacheRebuildThread.informOfQueueChange();
|
_cacheRebuildThread.informOfQueueChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<VClassGroup> getGroups( int portalId ){
|
public void clearGroupCache(){
|
||||||
return getGroups(getVCGDao(),portalId );
|
_groupListMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,10 +94,13 @@ public class VClassGroupCache{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearGroupCache(){
|
public List<VClassGroup> getGroups( int portalId ){
|
||||||
_groupListMap.clear();
|
return getGroups(getVCGDao(),portalId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<VClassGroup> getGroups( VClassGroupDao vcgDao, int portalId) {
|
||||||
|
return getGroups( vcgDao, portalId, INCLUDE_INDIVIDUAL_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
private List<VClassGroup> getGroups( VClassGroupDao vcgDao , int portalId, boolean includeIndividualCount ){
|
private List<VClassGroup> getGroups( VClassGroupDao vcgDao , int portalId, boolean includeIndividualCount ){
|
||||||
List<VClassGroup> groupList = _groupListMap.get(portalId);
|
List<VClassGroup> groupList = _groupListMap.get(portalId);
|
||||||
|
@ -117,10 +122,6 @@ public class VClassGroupCache{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<VClassGroup> getGroups( VClassGroupDao vcgDao, int portalId) {
|
|
||||||
return getGroups( vcgDao, portalId, INCLUDE_INDIVIDUAL_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestCacheUpdate(String portalUri){
|
private void requestCacheUpdate(String portalUri){
|
||||||
log.debug("requesting update for portal " + portalUri);
|
log.debug("requesting update for portal " + portalUri);
|
||||||
_rebuildQueue.add(portalUri);
|
_rebuildQueue.add(portalUri);
|
||||||
|
@ -254,14 +255,18 @@ public class VClassGroupCache{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestStop() {
|
private void requestStop() {
|
||||||
|
log.info("Killing the thread.");
|
||||||
_cacheRebuildThread.kill();
|
_cacheRebuildThread.kill();
|
||||||
|
|
||||||
|
try {
|
||||||
|
_cacheRebuildThread.join();
|
||||||
|
log.info("The thread is dead.");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Waiting for the thread to die, but interrupted.", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VClassGroupDao getVCGDao(){
|
protected VClassGroupDao getVCGDao(){
|
||||||
if( context == null ){
|
|
||||||
log.error("Context was not set for VClassGroupCache");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
WebappDaoFactory wdf =(WebappDaoFactory)context.getAttribute("webappDaoFactory");
|
WebappDaoFactory wdf =(WebappDaoFactory)context.getAttribute("webappDaoFactory");
|
||||||
if( wdf == null ){
|
if( wdf == null ){
|
||||||
log.error("Cannot get webappDaoFactory from context");
|
log.error("Cannot get webappDaoFactory from context");
|
||||||
|
@ -270,8 +275,6 @@ public class VClassGroupCache{
|
||||||
return wdf.getVClassGroupDao();
|
return wdf.getVClassGroupDao();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String REBUILD_EVERY_PORTAL ="Rebuild every portal.";
|
|
||||||
|
|
||||||
/* ****************** Jena Model Change Listener***************************** */
|
/* ****************** Jena Model Change Listener***************************** */
|
||||||
private class VClassGroupCacheChangeListener extends StatementListener {
|
private class VClassGroupCacheChangeListener extends StatementListener {
|
||||||
private VClassGroupCache cache = null;
|
private VClassGroupCache cache = null;
|
||||||
|
@ -304,62 +307,53 @@ public class VClassGroupCache{
|
||||||
}
|
}
|
||||||
/* ******************** RebuildGroupCacheThread **************** */
|
/* ******************** RebuildGroupCacheThread **************** */
|
||||||
protected class RebuildGroupCacheThread extends Thread {
|
protected class RebuildGroupCacheThread extends Thread {
|
||||||
VClassGroupCache cache;
|
private final VClassGroupCache cache;
|
||||||
boolean die = false;
|
private final AtomicLong queueChangeMillis = new AtomicLong();
|
||||||
boolean queueChange = false;
|
private volatile boolean die = false;
|
||||||
long queueChangeMills = 0;
|
|
||||||
private boolean awareOfQueueChange = false;
|
|
||||||
|
|
||||||
RebuildGroupCacheThread(VClassGroupCache cache) {
|
RebuildGroupCacheThread(VClassGroupCache cache) {
|
||||||
super("VClassGroupCache.RebuildGroupCacheThread");
|
super("VClassGroupCache.RebuildGroupCacheThread");
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
public void run() {
|
|
||||||
while(true){
|
|
||||||
try{
|
|
||||||
synchronized (this){
|
|
||||||
if( _rebuildQueue.isEmpty() ){
|
|
||||||
log.debug("rebuildGroupCacheThread.run() -- queye empty, sleep");
|
|
||||||
wait(1000 * 60 );
|
|
||||||
}
|
|
||||||
if( die ) {
|
|
||||||
log.debug("doing rebuildGroupCacheThread.run() -- die()");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( queueChange && !awareOfQueueChange){
|
|
||||||
log.debug("rebuildGroupCacheThread.run() -- awareOfQueueChange, delay start of rebuild");
|
|
||||||
awareOfQueueChange = true;
|
|
||||||
wait(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( awareOfQueueChange && System.currentTimeMillis() - queueChangeMills > 200){
|
public void run() {
|
||||||
|
while (!die) {
|
||||||
|
int delay;
|
||||||
|
|
||||||
|
if (_rebuildQueue.isEmpty()) {
|
||||||
|
log.debug("rebuildGroupCacheThread.run() -- queue empty, sleep");
|
||||||
|
delay = 1000 * 60;
|
||||||
|
} else if ((System.currentTimeMillis() - queueChangeMillis.get()) < 200) {
|
||||||
|
log.debug("rebuildGroupCacheThread.run() -- delay start of rebuild");
|
||||||
|
delay = 200;
|
||||||
|
} else {
|
||||||
log.debug("rebuildGroupCacheThread.run() -- refreshGroupCache()");
|
log.debug("rebuildGroupCacheThread.run() -- refreshGroupCache()");
|
||||||
cache.refreshGroupCache();
|
cache.refreshGroupCache();
|
||||||
synchronized( this){
|
delay = 0;
|
||||||
queueChange = false;
|
|
||||||
}
|
|
||||||
awareOfQueueChange = false;
|
|
||||||
}else {
|
|
||||||
synchronized( this ){
|
|
||||||
wait(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(InterruptedException e){}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delay > 0) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
wait(delay);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.warn("Waiting " + delay
|
||||||
|
+ " milliseconds, but interrupted.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("rebuildGroupCacheThread.run() -- die()");
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void informOfQueueChange(){
|
synchronized void informOfQueueChange(){
|
||||||
queueChange = true;
|
queueChangeMillis.set(System.currentTimeMillis());
|
||||||
queueChangeMills = System.currentTimeMillis();
|
|
||||||
this.notifyAll();
|
this.notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void kill(){
|
synchronized void kill(){
|
||||||
die = true;
|
die = true;
|
||||||
notifyAll();
|
this.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,11 +367,9 @@ public class VClassGroupCache{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
ServletContext servletContext = sce.getServletContext();
|
Object o = sce.getServletContext().getAttribute(ATTRIBUTE_NAME);
|
||||||
Object o = servletContext.getAttribute(ATTRIBUTE_NAME);
|
|
||||||
if (o instanceof VClassGroupCache) {
|
if (o instanceof VClassGroupCache) {
|
||||||
VClassGroupCache cache = (VClassGroupCache) o;
|
((VClassGroupCache) o).requestStop();
|
||||||
cache.requestStop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue