package org.limewire.core.impl.search;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import org.limewire.collection.Periodic;
import org.limewire.core.api.search.SearchManager;
import org.limewire.core.api.search.SearchResultList;
import com.google.inject.Inject;
import com.google.inject.name.Named;
/**
* A monitor for search results. SearchMonitor is used to automatically
* cancel searches that have not been referenced for a long period of time.
*/
class SearchMonitor {
/** Timeout period of 5 minutes. */
private static final long TIMEOUT_MSEC = 5 * 60 * 1000;
private final ScheduledExecutorService backgroundExecutor;
private final Map<SearchResultList, Periodic> resultMap;
private SearchManager searchManager;
/**
* Constructs a SearchMonitor.
*/
@Inject
public SearchMonitor(@Named("backgroundExecutor") ScheduledExecutorService backgroundExecutor) {
this.backgroundExecutor = backgroundExecutor;
this.resultMap = new ConcurrentHashMap<SearchResultList, Periodic>();
}
/**
* Sets the search manager.
*/
public void setSearchManager(SearchManager searchManager) {
this.searchManager = searchManager;
}
/**
* Adds the specified search result list to the set being monitored.
*/
public void addSearch(SearchResultList resultList) {
// Create periodic task and add to map of monitored results.
Periodic periodic = new Periodic(new CancelTask(resultList), backgroundExecutor);
resultMap.put(resultList, periodic);
// Schedule task to cancel search.
periodic.rescheduleIfLater(TIMEOUT_MSEC);
}
/**
* Removes the specified search result list from the set being monitored.
*/
public void removeSearch(SearchResultList resultList) {
Periodic periodic = resultMap.remove(resultList);
if (periodic != null) {
periodic.unschedule();
}
}
/**
* Updates the cancellation time of the specified search result list.
*/
public void updateSearch(SearchResultList resultList) {
Periodic periodic = resultMap.get(resultList);
if (periodic != null) {
periodic.rescheduleIfLater(TIMEOUT_MSEC);
}
}
/**
* Task to cancel a search. This is executed by the search monitor when
* it has determined that the search has timed out.
*/
private class CancelTask implements Runnable {
private final SearchResultList resultList;
public CancelTask(SearchResultList resultList) {
this.resultList = resultList;
}
@Override
public void run() {
// Stop search.
searchManager.stopSearch(resultList);
// Remove from search monitor.
removeSearch(resultList);
}
}
}