You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by cw...@apache.org on 2018/12/18 18:54:22 UTC

svn commit: r1849208 - in /uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent: ./ event/ launcher/ processors/

Author: cwiklik
Date: Tue Dec 18 18:54:22 2018
New Revision: 1849208

URL: http://svn.apache.org/viewvc?rev=1849208&view=rev
Log:
UIMA-5928 modified to prevent sending SIGTERM to non-preemptable processes during agent quiesce

Modified:
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/NodeAgent.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/ProcessLifecycleController.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/event/AgentEventListener.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/Launcher.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeMetricsProcessor.java
    uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/NodeAgent.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/NodeAgent.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/NodeAgent.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/NodeAgent.java Tue Dec 18 18:54:22 2018
@@ -883,7 +883,7 @@ public class NodeAgent extends AbstractD
    */
   public void reconcileProcessStateAndTakeAction(ProcessLifecycleController lifecycleController,
           IDuccProcess process, ICommandLine commandLine, IDuccStandardInfo info,
-          ProcessMemoryAssignment processMemoryAssignment, DuccId workDuccId) {
+          ProcessMemoryAssignment processMemoryAssignment, DuccId workDuccId, boolean isPreemptable) {
     String methodName = "reconcileProcessStateAndTakeAction";
     try {
       inventorySemaphore.acquire();
@@ -896,7 +896,7 @@ public class NodeAgent extends AbstractD
           if (process.isDeallocated() ) {
         	  // if agent is in stopping state, it will try to stop 
         	  // its processes. 
-        	  if ( stopping ) {
+        	  if ( stopping && isPreemptable ) {
         		  logger.info(
                           methodName,
                           workDuccId,
@@ -956,7 +956,7 @@ public class NodeAgent extends AbstractD
                               + process.getProcessState() + " Process Resource State:"
                               + process.getResourceState());
               lifecycleController.startProcess(process, commandLine, info, workDuccId,
-                      processMemoryAssignment);
+                      processMemoryAssignment, isPreemptable);
             }
           }
         }
@@ -969,7 +969,7 @@ public class NodeAgent extends AbstractD
   }
 
   public void doStartProcess(IDuccProcess process, ICommandLine commandLine,
-          IDuccStandardInfo info, DuccId workDuccId) {
+          IDuccStandardInfo info, DuccId workDuccId, boolean isPreemptable) {
     String methodName = "doStartProcess";
     try {
       inventorySemaphore.acquire();
@@ -978,7 +978,7 @@ public class NodeAgent extends AbstractD
                 + process.getDuccId() + " is already in agent's inventory.");
         return;
       }
-      startProcess(process, commandLine, info, workDuccId, new ProcessMemoryAssignment());
+      startProcess(process, commandLine, info, workDuccId, new ProcessMemoryAssignment(),isPreemptable);
     } catch (InterruptedException e) {
       logger.error(methodName, null, e);
     } finally {
@@ -1084,7 +1084,7 @@ public class NodeAgent extends AbstractD
    *
    */
   public void startProcess(IDuccProcess process, ICommandLine commandLine, IDuccStandardInfo info,
-          DuccId workDuccId, ProcessMemoryAssignment processMemoryAssignment) {
+          DuccId workDuccId, ProcessMemoryAssignment processMemoryAssignment, boolean isPreemptable) {
     String methodName = "startProcess";
 
     try {
@@ -1102,7 +1102,7 @@ public class NodeAgent extends AbstractD
                 "Rejecting Process Start Request. Process ID:" + process.getDuccId()
                         + " hava already been deallocated due to Shrink");
       } else {
-        deployProcess(process, commandLine, info, workDuccId, processMemoryAssignment);
+        deployProcess(process, commandLine, info, workDuccId, processMemoryAssignment,isPreemptable);
       }
 
     } catch (Exception e) {
@@ -1451,7 +1451,7 @@ public class NodeAgent extends AbstractD
    *          - fully defined command line that will be used to exec the process.
    */
   private void deployProcess(IDuccProcess process, ICommandLine commandLine,
-          IDuccStandardInfo info, DuccId workDuccId, ProcessMemoryAssignment processMemoryAssignment) {
+          IDuccStandardInfo info, DuccId workDuccId, ProcessMemoryAssignment processMemoryAssignment, boolean preemptable) {
     String methodName = "deployProcess";
     synchronized (monitor) {
       boolean deployProcess = true;
@@ -1477,7 +1477,7 @@ public class NodeAgent extends AbstractD
           tw.setEnd(null);
           process.setTimeWindowInit(tw);
           ManagedProcess managedProcess = new ManagedProcess(process, commandLine, this, logger,
-                  processMemoryAssignment);
+                  processMemoryAssignment, preemptable);
           managedProcess.setProcessInfo(info);
           managedProcess.setWorkDuccId(workDuccId);
 
@@ -1564,7 +1564,7 @@ public class NodeAgent extends AbstractD
 
   /**
    * This method is called when an agent receives a STOP request. It
-   * sends SIGTERM to all child processes and starts a timer. If the
+   * sends SIGTERM to all non-preemptable child processes and starts a timer. If the
    * timer pops and child processes are still running, the agent takes
    * itself out via halt()
    */
@@ -1574,25 +1574,19 @@ public class NodeAgent extends AbstractD
 	  try {
 		  Iterator<ManagedProcess> it = deployedProcesses.iterator();
 		  while( it.hasNext() ) {
-			  ManagedProcess deployedProcess = it.next();
-	     // for (ManagedProcess deployedProcess : deployedProcesses) {
-	          String pid = deployedProcess.getDuccProcess().getPID();
-	    	  logger.info(methodName, null, "....Process:"+pid+" is JD="+deployedProcess.isJd());
-	    	  // when called with quiesce=true we dont kill JDs to allow the JP
-	    	  // to send task completions. The JD's will be stopped when all JPs
-	    	  // terminate.
-//	    	  if ( deployedProcess.isStopping() || ( quiesceMode && deployedProcess.isJd()) ) {
-//	    	  if ( deployedProcess.isStopping() ) {
-//	    		  continue;
-//	    	  }
-            if (  deployedProcess.isStopping() || pid == null || pid.trim().length() == 0 || !runnable(deployedProcess) ) {
+			ManagedProcess deployedProcess = it.next();
+	        String pid = deployedProcess.getDuccProcess().getPID();
+	    	logger.info(methodName, null, "....Process:"+pid+" is JD="+deployedProcess.isJd()+" Preemptable:"+deployedProcess.isPreemptable());
+	    	// dont send SIGTERM to non-preemptable processes in quiesce mode
+            if (  (quiesceMode && !deployedProcess.isPreemptable()) || deployedProcess.isStopping() || pid == null || pid.trim().length() == 0 || !runnable(deployedProcess) ) {
             	continue;
             }
             
             logger.info(methodName, null, "....Stopping Process - DuccId:" + deployedProcess.getDuccProcess().getDuccId()
 	                    + " PID:" + pid+" Sending SIGTERM Process State:"+deployedProcess.getDuccProcess().getProcessState().toString()
 	                    +" Process Type:"+ deployedProcess.getDuccProcess().getProcessType()
-	                    +" Uima AS:"+deployedProcess.isUimaAs());
+	                    +" Uima AS:"+deployedProcess.isUimaAs()
+	                    +" Preemtable:"+deployedProcess.isPreemptable());
 			wait = true;
             deployedProcess.setStopPriority(StopPriority.DONT_WAIT);
             // Stop each child process in its own thread to parallelize SIGTERM requests
@@ -1607,24 +1601,24 @@ public class NodeAgent extends AbstractD
 	  return wait;
   }
 
-      private void killChildProcesses(boolean killOnlyUimaAs ) {
+      private void killChildProcesses(boolean killOnlyUimaAs, boolean quiesce) {
     	  String methodName = "killChildProcesses";
 
 
     	  try {
       	    if ( useCgroups ) {
-    	        logger.info("stop", null, "CgroupsManager.cleanup() before ");
+    	        logger.info(methodName, null, "CgroupsManager.cleanup() before ");
     	        if ( killOnlyUimaAs ) {
     	        	Set<String> pidsToKill = new HashSet<>();
     	        	Iterator<ManagedProcess> it = deployedProcesses.iterator();
     	        	while( it.hasNext() ) {
     	        		ManagedProcess p = it.next();
-    	        		if ( p.getPid() != null && p.isUimaAs()) {
+    	        		if ( !p.isPreemptable() && p.getPid() != null && p.isUimaAs()) {
     	        			pidsToKill.add(p.getPid());
     	        		}
     	        	}
     	        	if ( !pidsToKill.isEmpty() ) {
-        	        	System.out.println(">>>>>>>> Found "+pidsToKill.size()+" UIMA-AS processes still running - killing all via kill -9");
+    	        		logger.info(methodName, null, ">>>>>>>> Found "+pidsToKill.size()+" UIMA-AS processes still running - killing all non-preemptables via kill -9");
             	        // Since SIGTERM may not be enough to take down a process, use cgroups to find
             	        // any UIMA-AS process still standing and do hard kill
             	        cgroupsManager.cleanupPids(pidsToKill);
@@ -1632,19 +1626,28 @@ public class NodeAgent extends AbstractD
     	        	}
     	        	
     	        } else {
+    	        	Set<String> pidsToKill = new HashSet<>();
+    	        	Iterator<ManagedProcess> it = deployedProcesses.iterator();
         	        // Since SIGTERM may not be enough to take down a process, use cgroups to find
         	        // any process still standing and do hard kill
-        	        cgroupsManager.cleanup();
+    	        	while( it.hasNext() ) {
+    	        		ManagedProcess p = it.next();
+    	        		if ( (!quiesce && !p.isPreemptable()) && p.getPid() != null && p.isUimaAs()) {
+    	        			pidsToKill.add(p.getPid());
+    	        		}
+    	        	}
+    	        	//cgroupsManager.cleanup();
+        	        cgroupsManager.cleanupPids(pidsToKill);
     	        	
     	        }
-    	        logger.info("stop", null, "CgroupsManager.cleanup() after ");
+    	        logger.info(methodName, null, "CgroupsManager.cleanup() after ");
     	    } else {
     	    	Iterator<ManagedProcess> it = deployedProcesses.iterator();
     	    	while( it.hasNext() ) {
     	    		ManagedProcess deployedProcess = it.next();
     	    		
                   String pid = deployedProcess.getDuccProcess().getPID();
-                  if (pid == null || pid.trim().length() == 0 || !runnable(deployedProcess) ) {
+                  if ((quiesce && !deployedProcess.isPreemptable()) || pid == null || pid.trim().length() == 0 || !runnable(deployedProcess) ) {
                   	continue;
                   }
                   logger.info(methodName, null, "....Stopping Process - DuccId:" + deployedProcess.getDuccProcess().getDuccId()
@@ -1711,7 +1714,7 @@ public class NodeAgent extends AbstractD
                   + " Not in Agent's inventory. Adding to the inventory with state=Stopped");
           process.setProcessState(ProcessState.Stopped);
           inventory.put(process.getDuccId(), process);
-          processDeploy(new ManagedProcess(process, null, this, logger, new ProcessMemoryAssignment()));
+          processDeploy(new ManagedProcess(process, null, this, logger, new ProcessMemoryAssignment(), true));
     	  return;
       }
       
@@ -2004,6 +2007,10 @@ public class NodeAgent extends AbstractD
               .process(nmp);
     }
   }
+  @Override
+  public boolean isStopping() {
+	    return stopping;
+	}
     @Override
 	public void quiesceAndStop() throws Exception {
 		stop(true, -1);
@@ -2016,7 +2023,7 @@ public class NodeAgent extends AbstractD
 			}
 			stopping = true;
 			stateChange(EventType.SHUTDOWN);
-			// Dispatch SIGTERM to all child processes
+			// Dispatch SIGTERM to all processes. If this is quiesce mode we dont try to stop non-preemptable processes
 			boolean wait = stopChildProcesses(quiesce);
 			if ( quiesce ) {
 				logger.info("stop", null, "Agent stopping managed processes");
@@ -2030,35 +2037,26 @@ public class NodeAgent extends AbstractD
 				}
 				// Version 2.10.2 of UIMA-AS is not supporting quiesce and stop
 				// so we need to implement wait than kill -9 strategy.
-				waitForChildProcessesToTerminateAndKill(wait, waitTime, true);
+				waitForChildProcessesToTerminateAndKill(wait, waitTime, true, quiesce);
 				logger.info("stop", null,">>>>>>>>>>>> stop() waitForChildProcessesToTerminateAndKill() completed");
-				// wait for JP processes to terminate. Return only when all 
-				// terminate.
-				//waitForChildProcessesToTerminate(true);
-				//logger.info("stop", null,">>>>>>>>>>>> stop() waitForChildProcessesToTerminate() completed");
-				// now stop JDs
-				//stopChildProcesses(false);
-				//logger.info("stop", null,">>>>>>>>>>>> stop() stopChildProcesses() completed");
-				// wait for JD processes to terminate. Return only when all 
+				// wait for JD processes to terminate. Return only when all non-preemptables
 				// terminate.
 				waitForChildProcessesToTerminate(false);
-				logger.info("stop", null,">>>>>>>>>>>> stop() waitForChildProcessesToTerminate() 2 completed");
+				logger.info("stop", null,">>>>>>>>>>>> stop() waitForChildProcessesToTerminate() completed");
 			} else {
 				logger.info("stop", null, "Agent stopping managed processes with reaper delay of "+waitTimeInSecs+" secs");
 
 				// wait for 60 secs and sends SIGKILL to any process still standing
-				waitForChildProcessesToTerminateAndKill(wait, waitTimeInSecs, false);
+				waitForChildProcessesToTerminateAndKill(wait, waitTimeInSecs, false, quiesce);
 			}
 			// Send an empty process map as the final inventory
-//			HashMap<DuccId, IDuccProcess> emptyMap = new HashMap<>();
 			DuccEvent duccEvent = new NodeInventoryUpdateDuccEvent(inventory, getLastORSequence(), getIdentity());
-//			DuccEvent duccEvent = new NodeInventoryUpdateDuccEvent(emptyMap, getLastORSequence(), getIdentity());
 			ORDispatcher.dispatch(duccEvent);
 			logger.info("stop", null, "Agent published final inventory");
 			
 			logger.info("stop", null, "Stopping Publishing Metrics and Inventory");
 
-			//configurationFactory.stopRoutes();
+			
 			configurationFactory.stop();
 			logger.info("stop", null, "Reaper thread finished - calling super.stop()");
 			super.stop();
@@ -2071,36 +2069,21 @@ public class NodeAgent extends AbstractD
 	  stop(false, 60);
   }
 
-  private void waitForChildProcessesToTerminateAndKill(boolean wait, long waitTimeInSecs, boolean killJustUimaAs) throws Exception {
+  private void waitForChildProcessesToTerminateAndKill(boolean wait, long waitTimeInSecs, boolean killJustUimaAs, boolean quiesce) throws Exception {
 		if (wait && !deployedProcesses.isEmpty()) {
-			logger.info("waitForChildProcessesToTerminateAndKill", null, "Agent Sent SIGTERM to ALL Child Processes - Number of Deployed Processes:"
+			logger.info("waitForChildProcessesToTerminateAndKill", null, "Agent Sent SIGTERM to ALL Non-Preemptable Child Processes - Number of Deployed Processes:"
 					+ deployedProcesses.size());
 			
 			Timer timer = new Timer(true);
-			logger.info("waitForChildProcessesToTerminateAndKill", null, "Waiting", waitTimeInSecs, " secs before sending kill -9 to all child processes still running");
+			logger.info("waitForChildProcessesToTerminateAndKill", null, "Waiting", waitTimeInSecs, " secs before sending kill -9 to all ***non-preemptable*** child processes still running");
 			CountDownLatch completionLatch = new CountDownLatch(1);
 			// start a timer task which when triggered kills processes via kill -9
-			timer.schedule(new KillTimerTask(completionLatch, killJustUimaAs), waitTimeInSecs*1000);
+			timer.schedule(new KillTimerTask(completionLatch, killJustUimaAs, quiesce), waitTimeInSecs*1000);
 			
 			// block this thread until killer task finishes its work
 			completionLatch.await();
 			
-			// wait for awhile
-//			synchronized (this) {
-//				long waittime = 60000;
-//				if (configurationFactory.processStopTimeout != null) {
-//					try {
-//						waittime = Long.parseLong(configurationFactory.processStopTimeout);
-//					} catch (NumberFormatException e) {
-//						logger.warn("stop", null, e);
-//					}
-//				}
-//				logger.info("stop", null, "Waiting", waitTimeInSecs, " secs to send final NodeInventory.");
-//				this.wait(waitTimeInSecs*1000);
-//			}
 		}
-		// send kill -9 to any child process still running
-		//killChildProcesses();
 		stopLock.wait(1000);
 		logger.info("waitForChildProcessesToTerminateAndKill", null, "Done");
 
@@ -2125,15 +2108,6 @@ public class NodeAgent extends AbstractD
 			p.getFuture().get();
 			
 		}
-//		for (ManagedProcess p : deployedProcesses) {
-//			// dont wait for JDs to stop. In quiesce mode we keep them 
-//			// running until all JPs terminate and only than we stop them
-//			if ( quiesceMode && p.isJd()) {
-//					continue;
-//			}
-//			p.getFuture().get();
-//		}
-		
 	}
 
   public Future<?> getDeployedJPFuture(IDuccId duccId) {
@@ -2518,16 +2492,18 @@ public class NodeAgent extends AbstractD
 
 	private CountDownLatch completionLatch;
 	private boolean killJustUimaAs;
+	private boolean quiesce;
 	
-	public KillTimerTask(CountDownLatch completionLatch, boolean killOnlyUimaAs) {
+	public KillTimerTask(CountDownLatch completionLatch, boolean killOnlyUimaAs, boolean quiesce) {
 		this.completionLatch = completionLatch;
-		killJustUimaAs = killOnlyUimaAs;
+		this.killJustUimaAs = killOnlyUimaAs;
+		this.quiesce = quiesce;
 	}
 	@Override
 	public void run() {
 		try {
 			// send kill -9 to any child process still running
-			killChildProcesses(killJustUimaAs);
+			killChildProcesses(killJustUimaAs, quiesce);
 		} finally {
 			completionLatch.countDown();
 		}

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/ProcessLifecycleController.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/ProcessLifecycleController.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/ProcessLifecycleController.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/ProcessLifecycleController.java Tue Dec 18 18:54:22 2018
@@ -26,6 +26,6 @@ import org.apache.uima.ducc.transport.ev
 
 
 public interface ProcessLifecycleController {
-	public void startProcess(IDuccProcess process, ICommandLine commandLine, IDuccStandardInfo info, DuccId workDuccId, ProcessMemoryAssignment pma);
+	public void startProcess(IDuccProcess process, ICommandLine commandLine, IDuccStandardInfo info, DuccId workDuccId, ProcessMemoryAssignment pma, boolean isPreemptable);
 	public void stopProcess( IDuccProcess process );
 }

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/event/AgentEventListener.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/event/AgentEventListener.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/event/AgentEventListener.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/event/AgentEventListener.java Tue Dec 18 18:54:22 2018
@@ -126,14 +126,15 @@ public class AgentEventListener implemen
 						.getStandardInfo(),
 				jobDeployment
 						.getProcessMemoryAssignment(),
-				jobDeployment.getJobId());
+				jobDeployment.getJobId(), dw.getPreemptableStatus());
 
 	}
 	private void handleServiceState(IDuccJobDeployment jobDeployment, IDuccWork dw, IDuccProcess process) throws Exception {
 		logger.info("onDuccJobsStateEvent",
 				jobDeployment.getJobId(),
 				"SERVICE>>>>>>>>>>>> -PID:"
-						+ process.getPID());
+						+ process.getPID()+" Preemptable:"+dw.getPreemptableStatus());
+		
 		IDuccWorkJob service = (IDuccWorkJob) dw;
 		ICommandLine processCmdLine = service
 				.getCommandLine();
@@ -147,12 +148,13 @@ public class AgentEventListener implemen
 						.getStandardInfo(),
 				jobDeployment
 						.getProcessMemoryAssignment(),
-				jobDeployment.getJobId());
+				jobDeployment.getJobId(), dw.getPreemptableStatus());
 
 	}
 	private void handleJobDriverState(IDuccJobDeployment jobDeployment, Map<DuccId, IDuccProcess> processes) throws Exception {
 		IDuccWork dw = null;
 		boolean callReconcile = false;
+		boolean preemptable = false;
 		ICommandLine cmdLine = null;
 		// if driver not running, launch it
 		if ( !processes.containsKey(jobDeployment.getJdProcess().getDuccId())) {
@@ -166,6 +168,7 @@ public class AgentEventListener implemen
 					callReconcile = true;
 					cmdLine = driver.getCommandLine();
 				}
+				preemptable = dw.getPreemptableStatus();
             }
 		} else {
 			// driver running already. Still call reconcileProcessStateAndTakeAction()
@@ -174,7 +177,7 @@ public class AgentEventListener implemen
 		}
 		if ( callReconcile) {
 			  agent.reconcileProcessStateAndTakeAction(lifecycleController, jobDeployment.getJdProcess(), cmdLine,  
-						jobDeployment.getStandardInfo(), jobDeployment.getProcessMemoryAssignment(), jobDeployment.getJobId());
+						jobDeployment.getStandardInfo(), jobDeployment.getProcessMemoryAssignment(), jobDeployment.getJobId(), preemptable);
 
 		}
 	}
@@ -214,7 +217,7 @@ public class AgentEventListener implemen
 						agent.reconcileProcessStateAndTakeAction(lifecycleController,process,
 								null, jobDeployment.getStandardInfo(),
 								jobDeployment.getProcessMemoryAssignment(),
-								jobDeployment.getJobId());
+								jobDeployment.getJobId(), false);
 					}
 				} 
 			}  // for
@@ -337,7 +340,7 @@ public class AgentEventListener implemen
 			//  the agent will start a process.
 			if ( Utils.isTargetNodeForMessage(processEntry.getValue().getNodeIdentity().getIp(),agent.getIdentity().getIp()) ) { 
 				logger.info(">>> onProcessStartEvent", null,"... Agent ["+agent.getIdentity().getIp()+"] Matches Target Node Assignment:"+processEntry.getValue().getNodeIdentity().getIp()+" For Share Id:"+  processEntry.getValue().getDuccId());
-				agent.doStartProcess(processEntry.getValue(),duccEvent.getCommandLine(), duccEvent.getStandardInfo(), duccEvent.getDuccWorkId());
+				agent.doStartProcess(processEntry.getValue(),duccEvent.getCommandLine(), duccEvent.getStandardInfo(), duccEvent.getDuccWorkId(), true);
                 if ( processEntry.getValue().getProcessType().equals(ProcessType.Pop)) {
                 	break; // there should only be one JD process to launch
                 } else {

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/Launcher.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/Launcher.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/Launcher.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/Launcher.java Tue Dec 18 18:54:22 2018
@@ -109,7 +109,7 @@ public class Launcher {
         
     }
     /**
-     * This method is used to simulation only. It enables launching an agent with 
+     * This method is used for simulation only. It enables launching an agent with 
      * a given name and IP address which are different from a physical node name
      * and IP address. With that multiple agents can be launched on the same 
      * physical machine simulating a cluster of nodes.

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/ManagedProcess.java Tue Dec 18 18:54:22 2018
@@ -141,27 +141,32 @@ public class ManagedProcess implements P
 	private long initializationTimeout;
 
 	private volatile boolean isUimaAs;
+	private volatile boolean preemptable;
 	
 	public ManagedProcess(IDuccProcess process, ICommandLine commandLine) {
-		this(process, commandLine, null, null, new ProcessMemoryAssignment());
+		this(process, commandLine, null, null, new ProcessMemoryAssignment(), true);
 	}
 
 	public ManagedProcess(IDuccProcess process, ICommandLine commandLine,
 			boolean agentProcess) {
-		this(process, commandLine, null, null, new ProcessMemoryAssignment());
+		this(process, commandLine, null, null, new ProcessMemoryAssignment(), true);
 		this.agentProcess = agentProcess;
 	}
 
 	public ManagedProcess(IDuccProcess process, ICommandLine commandLine,
 			ProcessLifecycleObserver observer, DuccLogger logger,
-			ProcessMemoryAssignment processMemoryAssignment) {
+			ProcessMemoryAssignment processMemoryAssignment, boolean isPreemptable) {
 		this.commandLine = commandLine;
 		this.duccProcess = process;
 		this.observer = observer;
 		this.logger = logger;
 		this.processMemoryAssignment = processMemoryAssignment;
+		this.preemptable = isPreemptable;
 	}
 
+	public boolean isPreemptable() {
+		return preemptable;
+	}
 	public void setMetricsProcessor(LinuxProcessMetricsProcessor processor) {
 		metricsProcessor = processor;
 	}

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeMetricsProcessor.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeMetricsProcessor.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeMetricsProcessor.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/DefaultNodeMetricsProcessor.java Tue Dec 18 18:54:22 2018
@@ -82,6 +82,7 @@ public class DefaultNodeMetricsProcessor
 	                    cpuInfo, nuiFuture.get(), cpuReportingEnabled);
 	    if ( agent.isStopping()) {
 	    	nodeMetrics.disableNode();  // sends Unavailable status to clients (RM,WS)
+	    	logger.info(methodName, null,">>>>>>>>>>>>>>>>> Agent publishing State="+nodeMetrics.getNodeStatus()+" in Outgoing NodeMetrics");
 	    }
 	    //Node node = new DuccNode(new NodeIdentity(), nodeMetrics);
 	    // jrc 2011-07-30 I think this needs to be agent.getIdentity(), not create a new identity.

Modified: uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java
URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java?rev=1849208&r1=1849207&r2=1849208&view=diff
==============================================================================
--- uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java (original)
+++ uima/uima-ducc/trunk/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/processors/LinuxNodeMetricsProcessor.java Tue Dec 18 18:54:22 2018
@@ -157,7 +157,10 @@ public class LinuxNodeMetricsProcessor e
 			}
             NodeMetrics nodeMetrics = new NodeMetrics(agent.getIdentity(), memInfo, lav,
               cpuInfo, users, cpuReportingEnabled);
-      
+    	    if ( agent.isStopping()) {
+    	    	nodeMetrics.disableNode();  // sends Unavailable status to clients (RM,WS)
+    	    }
+
 			Node node = new DuccNode(agent.getIdentity(), nodeMetrics, agent.useCgroups);
 			// Make the agent aware how much memory is available on the node. Do this once.
 			if ( agent.getNodeInfo() == null ) {
@@ -178,7 +181,8 @@ public class LinuxNodeMetricsProcessor e
 					" Swap Total (KB):"+node.getNodeMetrics().getNodeMemory().getSwapTotal()+
 					" Swap Free (KB):"+node.getNodeMetrics().getNodeMemory().getSwapFree()+
 					" Low Swap Threshold Defined in ducc.properties (KB):"+swapThreshold +
-					" CPU Reporting Enabled:"+cpuReportingEnabled) ;
+					" CPU Reporting Enabled:"+cpuReportingEnabled +
+					" Node Status:"+nodeMetrics.getNodeStatus()) ;
 			
 			logger.trace(methodName, null, "... Agent "+node.getNodeIdentity().getCanonicalName()+" Posting Users:"+
 					node.getNodeMetrics().getNodeUsersMap().size());