/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/search/trunk/search-impl/impl/src/java/org/sakaiproject/search/journal/impl/ConcurrentIndexManager.java $ * $Id: ConcurrentIndexManager.java 105078 2012-02-24 23:00:38Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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 org.sakaiproject.search.journal.impl; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.IndexSearcher; import org.sakaiproject.search.api.SearchService; import org.sakaiproject.search.journal.api.IndexListener; import org.sakaiproject.search.journal.api.ManagementOperation; /** * The ConcurrentIndexManager, manages a single thread performs a number of * tasks associated with index management. * * @author ieb Unit test * @see org.sakaiproject.search.indexer.impl.test.ConcurrentIndexManagerTest */ public class ConcurrentIndexManager implements IndexListener { protected static final Log log = LogFactory.getLog(ConcurrentIndexManager.class); private Timer timer = new Timer("IndexManager",true); private List<IndexManagementTimerTask> tasks; private int nsopen = 0; private int nropen = 0; private SearchService searchService; private IndexListenerCloser indexListenerCloser; private static ThreadLocal<ManagementOperation> runningOperation = new ThreadLocal<ManagementOperation>(); public void init() { if (!searchService.isEnabled()) { return; } for (Iterator<IndexManagementTimerTask> i = tasks.iterator(); i.hasNext();) { IndexManagementTimerTask task = i.next(); if (task.isFixedRate()) { timer.scheduleAtFixedRate(task, task.getDelay(), task.getPeriod()); } else { timer.schedule(task, task.getDelay(), task.getPeriod()); } } if ( indexListenerCloser == null ) { indexListenerCloser = new IndexListenerCloser(); } timer.schedule(new TimerTask() { @Override public void run() { log.debug("Start Purge ------------------------- " + indexListenerCloser.size()); indexListenerCloser.purge(); log.debug("Purge complete ----------------------" + indexListenerCloser.size()); } }, 5000, 15000); } public void destroy() { close(); cleanup(); } public void close() { timer.cancel(); for (IndexManagementTimerTask itt : tasks) { itt.setClosed(true); } } public void cleanup() { indexListenerCloser.cleanup(); log.debug("N Searchers is " + nsopen); log.debug("N Readers is " + nropen); } /** * @return the tasks */ public List<IndexManagementTimerTask> getTasks() { return tasks; } /** * @param tasks * the tasks to set */ public void setTasks(List<IndexManagementTimerTask> tasks) { this.tasks = tasks; } /* * (non-Javadoc) * * @see org.sakaiproject.search.journal.api.IndexListener#doIndexReaderClose(org.apache.lucene.index.IndexReader) */ public void doIndexReaderClose(IndexReader oldMultiReader) throws IOException { nropen--; log.debug("Closed Reader " + nropen + " " + oldMultiReader); indexListenerCloser.doIndexReaderClose(oldMultiReader); } /* * (non-Javadoc) * * @see org.sakaiproject.search.journal.api.IndexListener#doIndexSearcherClose(org.apache.lucene.search.IndexSearcher) */ public void doIndexSearcherClose(IndexSearcher indexSearcher) throws IOException { nsopen--; log.debug("Closed Searcher " + nsopen + " " + indexSearcher); indexListenerCloser.doIndexSearcherClose(indexSearcher); } /** * @see org.sakaiproject.search.journal.api.IndexListener#doIndexSearcherOpen(org.apache.lucene.search.IndexSearcher) */ public void doIndexSearcherOpen(IndexSearcher indexSearcher) { nsopen++; log.debug(this + "Opened New Searcher " + nsopen + " " + indexSearcher); indexListenerCloser.doIndexSearcherOpen(indexSearcher); } /* * (non-Javadoc) * * @see org.sakaiproject.search.journal.api.IndexListener#doIndexReaderOpen(org.apache.lucene.index.IndexReader) */ public void doIndexReaderOpen(IndexReader newMultiReader) { nropen++; log.debug("Opened New Reader " + nropen + " " + newMultiReader); indexListenerCloser.doIndexReaderOpen(newMultiReader); } /** * @return the searchService */ public SearchService getSearchService() { return searchService; } /** * @param searchService * the searchService to set */ public void setSearchService(SearchService searchService) { this.searchService = searchService; } /** * @return the indexListenerCloser */ public IndexListenerCloser getIndexListenerCloser() { return indexListenerCloser; } /** * @param indexListenerCloser the indexListenerCloser to set */ public void setIndexListenerCloser(IndexListenerCloser indexListenerCloser) { this.indexListenerCloser = indexListenerCloser; } /** * @param managementOperation */ public static void setRunning(ManagementOperation managementOperation) { runningOperation.set(managementOperation); } /** * @return */ public static ManagementOperation getCurrentManagementOperation() { return runningOperation.get(); } }