Merge "Issue #1383 fix grid_info purging Change-Id: I275869e9c9c93ed345298e1ef5e746a80e5f4b27" into development

Former-commit-id: 8a7a8a4251 [formerly 63405d17d2] [formerly 8a7a8a4251 [formerly 63405d17d2] [formerly b7fdfc761b [formerly 50c1fb6a95fddbc7d7543c7bc0f5d33147229f03]]]
Former-commit-id: b7fdfc761b
Former-commit-id: ad126ebd0b [formerly 049f06e689]
Former-commit-id: fa4bbd62b3
This commit is contained in:
Richard Peter 2012-12-04 15:37:21 -06:00 committed by Gerrit Code Review
commit c53cd0d897

View file

@ -20,13 +20,18 @@
package com.raytheon.uf.edex.plugin.grid.dao;
import java.lang.ref.SoftReference;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import com.raytheon.uf.common.dataplugin.grid.GridInfoRecord;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils.LockState;
import com.raytheon.uf.edex.database.cluster.ClusterTask;
import com.raytheon.uf.edex.database.dao.CoreDao;
import com.raytheon.uf.edex.database.dao.DaoConfig;
@ -69,27 +74,9 @@ public class GridInfoCache {
public GridInfoRecord getGridInfo(GridInfoRecord record) {
GridInfoRecord result = checkLocalCache(record);
if (result == null) {
synchronized (this) {
// It is possible that this query will return multiple results,
// for example if the record we are looking for has a null
// secondaryId but some db entries have a secondaryId set then
// this query will return all matching models ignoring
// secondaryId. In general these cases should be rare and small.
// So we handle it by caching everything returned and then
// double checking the cache.
List<PersistableDataObject<Integer>> dbList = dao
.queryByExample(record);
if (dbList != null && !dbList.isEmpty()) {
for (PersistableDataObject<Integer> pdo : dbList) {
GridInfoRecord gir = (GridInfoRecord) pdo;
cache.put(gir, new SoftReference<GridInfoRecord>(gir));
}
}
result = checkLocalCache(record);
if (result == null) {
dao.saveOrUpdate(record);
result = record;
}
result = query(record);
if (result == null) {
result = insert(record);
}
}
return result;
@ -104,9 +91,78 @@ public class GridInfoCache {
return result;
}
public void purgeCache(List<Integer> modelKeys) {
for (Integer key : modelKeys) {
cache.remove(key);
/**
* Query the database for a record, if a record is found then it will be
* added to the cache and returned.
*
* @param record
* @return
*/
private GridInfoRecord query(GridInfoRecord record) {
// It is possible that this query will return multiple
// results, for example if the record we are looking for has
// a null secondaryId but some db entries have a secondaryId
// set then this query will return all matching models
// ignoring secondaryId. In general these cases should be
// rare and small. So we handle it by caching everything
// returned and then double checking the cache.
List<PersistableDataObject<Integer>> dbList = dao
.queryByExample(record);
if (dbList != null && !dbList.isEmpty()) {
for (PersistableDataObject<Integer> pdo : dbList) {
GridInfoRecord gir = (GridInfoRecord) pdo;
// if we don't remove then when an entry exists already the key
// and value become references to different objects which is not
// what we want.
cache.remove(gir);
cache.put(gir, new SoftReference<GridInfoRecord>(gir));
}
}
return checkLocalCache(record);
}
/**
* Insert the record into the database if there is no current record that
* equals this one. This method uses a fairly broad cluster lock so only one
* thread at a time across all clustered edices can insert at a time. This
* method should not be used much on running systems since gridded models
* maintain fairly consistent info records over time.
*
* @param record
* @return
*/
private GridInfoRecord insert(GridInfoRecord record) {
ClusterTask ct = null;
do {
ct = ClusterLockUtils.lock("grid_info", "newEntry", 30000, true);
} while (!LockState.SUCCESSFUL.equals(ct.getLockState()));
try {
GridInfoRecord existing = query(record);
if (existing != null) {
return existing;
}
dao.saveOrUpdate(record);
} finally {
ClusterLockUtils.unlock(ct, false);
}
cache.put(record, new SoftReference<GridInfoRecord>(record));
return record;
}
/**
* Remove the info records with the specified ids from the cache.
*
* @param infoKeys
*/
public void purgeCache(Collection<Integer> infoKeys) {
synchronized (cache) {
Iterator<GridInfoRecord> it = cache.keySet().iterator();
while (it.hasNext()) {
GridInfoRecord next = it.next();
if (infoKeys.contains(next.getId())) {
it.remove();
}
}
}
}