Merge "Issue #1515: Move blocking VCParm calls off of the ParmListener notification threads." into development

Former-commit-id: d8878cfd97 [formerly 237b728039] [formerly d8878cfd97 [formerly 237b728039] [formerly ed1e096a11 [formerly 1f809b6b94e9a0d3d96542bea9781cbc6397572d]]]
Former-commit-id: ed1e096a11
Former-commit-id: dd437f3df4 [formerly ee4c0568bf]
Former-commit-id: 86c52667ae
This commit is contained in:
Ron Anderson 2013-01-23 16:46:42 -06:00 committed by Gerrit Code Review
commit f24c9b9456
3 changed files with 103 additions and 70 deletions

View file

@ -32,9 +32,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.TreeSet;
import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.ListenerList;
@ -65,7 +63,6 @@ import com.raytheon.viz.gfe.GFEServerException;
import com.raytheon.viz.gfe.PythonPreferenceStore; import com.raytheon.viz.gfe.PythonPreferenceStore;
import com.raytheon.viz.gfe.core.DataManager; import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.IParmManager; import com.raytheon.viz.gfe.core.IParmManager;
import com.raytheon.viz.gfe.core.griddata.IGridData;
import com.raytheon.viz.gfe.core.internal.NotificationRouter.AbstractGFENotificationObserver; import com.raytheon.viz.gfe.core.internal.NotificationRouter.AbstractGFENotificationObserver;
import com.raytheon.viz.gfe.core.msgs.IAvailableSourcesChangedListener; import com.raytheon.viz.gfe.core.msgs.IAvailableSourcesChangedListener;
import com.raytheon.viz.gfe.core.msgs.IDisplayedParmListChangedListener; import com.raytheon.viz.gfe.core.msgs.IDisplayedParmListChangedListener;
@ -101,6 +98,8 @@ import com.raytheon.viz.gfe.core.parm.vcparm.VCModuleJobPool;
* execution. * execution.
* 08/20/2012 #1082 randerso Moved calcStepTimes to AbstractParmManager for * 08/20/2012 #1082 randerso Moved calcStepTimes to AbstractParmManager for
* use in PngWriter * use in PngWriter
* 01/22/2013 #1515 dgilling Increase default size of VCModule thread pool
* to decrease UI hang-ups waiting for results.
* *
* </pre> * </pre>
* *
@ -281,7 +280,7 @@ public abstract class AbstractParmManager implements IParmManager {
// Get virtual parm definitions // Get virtual parm definitions
vcModules = initVirtualCalcParmDefinitions(); vcModules = initVirtualCalcParmDefinitions();
vcModulePool = new VCModuleJobPool("GFE Virtual ISC Python executor", vcModulePool = new VCModuleJobPool("GFE Virtual ISC Python executor",
this.dataManager, vcModules.size(), Boolean.TRUE); this.dataManager, vcModules.size() + 2, Boolean.TRUE);
PythonPreferenceStore prefs = Activator.getDefault() PythonPreferenceStore prefs = Activator.getDefault()
.getPreferenceStore(); .getPreferenceStore();

View file

@ -24,9 +24,8 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import org.eclipse.core.runtime.IStatus; import java.util.concurrent.Executors;
import org.eclipse.core.runtime.Status;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory; import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
@ -40,7 +39,6 @@ import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.util.RWLArrayList; import com.raytheon.uf.common.util.RWLArrayList;
import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.core.DataManager; import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.griddata.AbstractGridData; import com.raytheon.viz.gfe.core.griddata.AbstractGridData;
import com.raytheon.viz.gfe.core.griddata.IGridData; import com.raytheon.viz.gfe.core.griddata.IGridData;
@ -74,6 +72,10 @@ import com.raytheon.viz.gfe.core.parm.vcparm.VCModule.VCInventory;
* Jun 25, 2012 #766 dgilling Cleanup error logging so we * Jun 25, 2012 #766 dgilling Cleanup error logging so we
* don't spam alertViz in practice * don't spam alertViz in practice
* mode. * mode.
* Jan 22, 2013 #1515 dgilling Handle Parm notifications on
* separate thread to prevent backup
* in ParmListener's notification job
* pool.
* *
* </pre> * </pre>
* *
@ -93,6 +95,8 @@ public class VCParm extends VParm implements IParmListChangedListener,
private List<VCInventory> vcInventory; private List<VCInventory> vcInventory;
private final ExecutorService notificationWorkers;
/** /**
* Constructor for Virtual Calculated Parm. * Constructor for Virtual Calculated Parm.
* *
@ -111,18 +115,15 @@ public class VCParm extends VParm implements IParmListChangedListener,
// Need to check that the above call to mod.getGpi() did not fail // Need to check that the above call to mod.getGpi() did not fail
if (!mod.isValid()) { if (!mod.isValid()) {
//statusHandler.handle(Priority.EVENTB, "Can't get GPI: ", statusHandler.handle(Priority.EVENTB, "Can't get GPI: ",
// this.mod.getErrorString()); this.mod.getErrorString());
Activator
.getDefault()
.getLog()
.log(new Status(IStatus.INFO, Activator.PLUGIN_ID,
"Can't get GPI: " + this.mod.getErrorString()));
} }
// set the parm type // set the parm type
// setParmType(Parm::VCPARM); // setParmType(Parm::VCPARM);
notificationWorkers = Executors.newSingleThreadExecutor();
// Determine dependent parms, and register for their ParmClient // Determine dependent parms, and register for their ParmClient
// notifications, determine initial inventory // notifications, determine initial inventory
registerParmClients(dataMgr.getParmManager().getAllParms(), false); registerParmClients(dataMgr.getParmManager().getAllParms(), false);
@ -141,6 +142,8 @@ public class VCParm extends VParm implements IParmListChangedListener,
for (Parm reg : registeredParms()) { for (Parm reg : registeredParms()) {
unregisterPC(reg); unregisterPC(reg);
} }
notificationWorkers.shutdownNow();
} }
/* /*
@ -153,27 +156,33 @@ public class VCParm extends VParm implements IParmListChangedListener,
*/ */
@Override @Override
public void gridDataChanged(final ParmID parmId, final TimeRange validTime) { public void gridDataChanged(final ParmID parmId, final TimeRange validTime) {
synchronized (this) { Runnable onNotificationTask = new Runnable() {
@Override
public void run() {
synchronized (VCParm.this) {
if (disposed) { if (disposed) {
return; return;
} }
} }
// statusHandler.handle(Priority.DEBUG, "gridDataChanged for: " + parmId // statusHandler.handle(Priority.DEBUG, "gridDataChanged for: "
// + parmId
// + " " + validTime); // + " " + validTime);
for (VCInventory inv : this.vcInventory) { for (VCInventory inv : vcInventory) {
for (DepParmInv dpi : inv.getDepParmInv()) { for (DepParmInv dpi : inv.getDepParmInv()) {
if (dpi.getParmID().equals(parmId)) { if (dpi.getParmID().equals(parmId)) {
for (TimeRange tr : dpi.getTimes()) { for (TimeRange tr : dpi.getTimes()) {
if (tr.getStart().equals(validTime.getStart())) { if (tr.getStart().equals(validTime.getStart())) {
this.grids.acquireReadLock(); grids.acquireReadLock();
try { try {
for (IGridData grid : this.grids) { for (IGridData grid : grids) {
if (inv.getGridTimeRange().equals( if (inv.getGridTimeRange().equals(
grid.getGridTime())) { grid.getGridTime())) {
grid.depopulate(); grid.depopulate();
gridDataHasChanged(grid, gridDataHasChanged(
grid,
getDisplayAttributes() getDisplayAttributes()
.getDisplayMask(), .getDisplayMask(),
false); false);
@ -181,7 +190,7 @@ public class VCParm extends VParm implements IParmListChangedListener,
} }
} }
} finally { } finally {
this.grids.releaseReadLock(); grids.releaseReadLock();
} }
} }
} }
@ -189,6 +198,10 @@ public class VCParm extends VParm implements IParmListChangedListener,
} }
} }
} }
};
notificationWorkers.submit(onNotificationTask);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -202,12 +215,17 @@ public class VCParm extends VParm implements IParmListChangedListener,
@Override @Override
public void parmListChanged(final Parm[] parms, Parm[] deletions, public void parmListChanged(final Parm[] parms, Parm[] deletions,
Parm[] additions) { Parm[] additions) {
Runnable onNotificationTask = new Runnable() {
@Override
public void run() {
// forcing access to the disposed variable and subsequent // forcing access to the disposed variable and subsequent
// registration/unregistation of listeners through this synchronized // registration/unregistation of listeners through this
// block seems to prevent VCParm objects being leaked through outdated // synchronized
// block seems to prevent VCParm objects being leaked through
// outdated
// listener list copies // listener list copies
synchronized (this) { synchronized (VCParm.this) {
if (disposed) { if (disposed) {
return; return;
} }
@ -219,6 +237,10 @@ public class VCParm extends VParm implements IParmListChangedListener,
registerParmClients(parms, true); registerParmClients(parms, true);
} }
} }
};
notificationWorkers.submit(onNotificationTask);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -239,7 +261,11 @@ public class VCParm extends VParm implements IParmListChangedListener,
// + getParmID().toString()); // + getParmID().toString());
// System.out.println("ParmInventoryChanged notification for: " // System.out.println("ParmInventoryChanged notification for: "
// + getParmID().toString()); // + getParmID().toString());
synchronized (this) { Runnable onNotificationTask = new Runnable() {
@Override
public void run() {
synchronized (VCParm.this) {
if (disposed) { if (disposed) {
return; return;
} }
@ -247,6 +273,10 @@ public class VCParm extends VParm implements IParmListChangedListener,
recalcInventory(true); recalcInventory(true);
} }
};
notificationWorkers.submit(onNotificationTask);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -464,14 +494,15 @@ public class VCParm extends VParm implements IParmListChangedListener,
// get list of dependent parms // get list of dependent parms
List<ParmID> args = new ArrayList<ParmID>(mod.dependentParms()); List<ParmID> args = new ArrayList<ParmID>(mod.dependentParms());
if (!mod.isValid()) { if (!mod.isValid()) {
//statusHandler.handle(Priority.EVENTB, statusHandler.handle(Priority.EVENTB,
// "Error getting dependent WeatherElements: ", "Error getting dependent WeatherElements: ",
// mod.getErrorString()); mod.getErrorString());
Activator // Activator
.getDefault() // .getDefault()
.getLog() // .getLog()
.log(new Status(IStatus.INFO, Activator.PLUGIN_ID, // .log(new Status(IStatus.INFO, Activator.PLUGIN_ID,
"Error getting dependent WeatherElements: " + this.mod.getErrorString())); // "Error getting dependent WeatherElements: "
// + this.mod.getErrorString()));
} }
// get list of currently registered parms // get list of currently registered parms

View file

@ -72,6 +72,8 @@ import com.raytheon.viz.gfe.core.parm.Parm;
* Oct 17, 2011 dgilling Initial creation * Oct 17, 2011 dgilling Initial creation
* Jun 20, 2012 #766 dgilling Refactor to improve * Jun 20, 2012 #766 dgilling Refactor to improve
* performance. * performance.
* Jan 22, 2013 #1515 dgilling Fix ClassCastException in
* getMethodArgs().
* *
* </pre> * </pre>
* *
@ -189,8 +191,9 @@ public class VCModule {
parmMgr.getVCModulePool().enqueue(req); parmMgr.getVCModulePool().enqueue(req);
Object result = req.getResult(); Object result = req.getResult();
String[] argNames = (String[]) result; @SuppressWarnings("unchecked")
return Arrays.asList(argNames); List<String> argNames = (List<String>) result;
return argNames;
} }
public Collection<ParmID> dependentParms() { public Collection<ParmID> dependentParms() {