Merge "Issue #1383 fix grid_info purging Change-Id: I275869e9c9c93ed345298e1ef5e746a80e5f4b27" into development
Former-commit-id:8a7a8a4251
[formerly63405d17d2
] [formerly8a7a8a4251
[formerly63405d17d2
] [formerlyb7fdfc761b
[formerly 50c1fb6a95fddbc7d7543c7bc0f5d33147229f03]]] Former-commit-id:b7fdfc761b
Former-commit-id:ad126ebd0b
[formerly049f06e689
] Former-commit-id:fa4bbd62b3
This commit is contained in:
commit
c53cd0d897
1 changed files with 80 additions and 24 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue