You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ch...@apache.org on 2014/02/03 20:35:49 UTC

svn commit: r1564022 [1/5] - in /uima/sandbox/uima-ducc/trunk: uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/ uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/servi...

Author: challngr
Date: Mon Feb  3 19:35:48 2014
New Revision: 1564022

URL: http://svn.apache.org/r1564022
Log:
UIMA-3405 SM Rework

Added:
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceInstance.java   (with props)
Modified:
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsPing.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsServiceMonitor.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccProperties.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_0.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_1.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_2.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_3.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_4.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_5.xml
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceMeta.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingDriver.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceHandler.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceManagerComponent.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServicePingMain.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/SmConstants.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceModifyEvent.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/ServiceRegisterEvent.java

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java Mon Feb  3 19:35:48 2014
@@ -18,6 +18,8 @@
 */
 package org.apache.uima.ducc.cli;
 
+import java.util.Properties;
+
 import org.apache.uima.ducc.common.IServiceStatistics;
 
 /**
@@ -27,9 +29,7 @@ import org.apache.uima.ducc.common.IServ
 public abstract class AServicePing
 {
 
-    int implementors = 0;
-    int references = 0;
-    int runFailures = 0;
+    protected Properties smState;
 
     /**
      * Called by the ping driver, to pass in useful things the pinger may want.
@@ -54,44 +54,25 @@ public abstract class AServicePing
      */
     public abstract IServiceStatistics getStatistics();
     
-    public int countAdditions()
-    {
-        return 0;
-    }
-
-    public int countDeletions()
-    {
-        return 0;
-    }
 
-    public int countImplementors()
+    public void setSmState(Properties props)
     {
-    	return implementors;
+        smState = props;
     }
 
-    public int countReferences()
+    public Properties getSmState() 
     {
-    	return references;
+        return smState;
     }
 
-    public void setImplementors(int imp)
+    public int getAdditions()
     {
-        this.implementors = imp;
-    }
-
-    public void setReferences(int ref)
-    {
-        this.references = ref;
-    }
-
-    public void setRunFailures(int e)
-    {
-        this.runFailures = e;
+        return 0;
     }
 
-    public int getRunFailures()
+    public int getDeletions()
     {
-        return this.runFailures;
+        return 0;
     }
 
     public boolean isExcessiveFailures()

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java Mon Feb  3 19:35:48 2014
@@ -117,6 +117,12 @@ public class DuccServiceApi 
         UiOption.Instances,
         UiOption.Autostart,
         UiOption.Activate,
+        UiOption.ServicePingArguments,
+        UiOption.ServicePingClass,
+        UiOption.ServicePingClasspath,
+        UiOption.ServicePingJvmArgs,
+        UiOption.ServicePingTimeout,
+        UiOption.ServicePingDoLog,
     }; 
 
     UiOption[] query_options = {
@@ -188,6 +194,7 @@ public class DuccServiceApi 
         return instances;
     }
 
+
     private boolean getActivate()
     {
         return cli_props.containsKey(UiOption.Activate.pname());
@@ -426,21 +433,45 @@ public class DuccServiceApi 
         throws Exception
     {
         DuccProperties dp = new DuccProperties();
+
         init (this.getClass().getName(), modify_options, args, null, dp, callback, "sm");
 
         Pair<Integer, String> id = getId(UiOption.Modify);
         String user = dp.getProperty(UiOption.User.pname());
         byte[] auth_block = (byte[]) dp.get(UiOption.Signature.pname());
 
-        ServiceModifyEvent ev = new ServiceModifyEvent(user, id.first(), id.second(), auth_block);
+        DuccProperties mods = new DuccProperties();        
+        ServiceModifyEvent ev = new ServiceModifyEvent(user, id.first(), id.second(), mods, auth_block);
         int instances = getInstances(-1);
         Trinary autostart = getAutostart();
         boolean activate = getActivate();
+        String  pingArguments = cli_props.getProperty(UiOption.ServicePingArguments.pname());
+        String  pingClass     = cli_props.getProperty(UiOption.ServicePingClass.pname());
+        String  pingClasspath = cli_props.getProperty(UiOption.ServicePingClasspath.pname());
+        String  pingJvmArgs   = cli_props.getProperty(UiOption.ServicePingJvmArgs.pname());
+        String  pingTimeout   = cli_props.getProperty(UiOption.ServicePingTimeout.pname());
+        String  pingDoLog     = cli_props.getProperty(UiOption.ServicePingDoLog.pname());
 
-        ev.setInstances(instances);
-        ev.setAutostart(autostart);
-        ev.setActivate(activate);
+        // modify: if something is modified, indicate the new value.  if no value, then it's not modified.
         
+        if ( instances > 0 ) mods.setProperty("instances", Integer.toString(instances));
+        switch ( autostart ) {
+            case True:  mods.setProperty("autostart", "true"); break;
+            case False: mods.setProperty("autostart", "false"); break;
+            default:
+                break;
+        }
+        if ( activate ) mods.setProperty("activate", "true");
+        else            mods.setProperty("activate", "false");
+
+        if ( pingArguments != null ) mods.setProperty("service_ping_arguments", pingArguments);
+        if ( pingClass     != null ) mods.setProperty("service_ping_class"    , pingClass);
+        if ( pingClasspath != null ) mods.setProperty("service_ping_classpath", pingClasspath);
+        if ( pingJvmArgs   != null ) mods.setProperty("service_ping_jvm_args" , pingJvmArgs);
+        if ( pingTimeout   != null ) mods.setProperty("service_ping_timeout"  , pingTimeout);
+        if ( pingDoLog     != null ) mods.setProperty("service_ping_dolog"    , pingDoLog);
+        
+
         try {
             return (IServiceReply) dispatcher.dispatchAndWaitForDuccReply(ev);
         } finally {

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java Mon Feb  3 19:35:48 2014
@@ -315,7 +315,6 @@ public interface IUiOptions
             public String argname()     { return "time-in-ms"; }
             public String description() { return "Time in milliseconds to wait for a ping to the service."; }
             public String example()     { return "1000"; }
-            public String deflt()       { return "500"; }
             public String label()       { return name(); }
         },            
 

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsPing.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsPing.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsPing.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsPing.java Mon Feb  3 19:35:48 2014
@@ -35,7 +35,6 @@ import org.apache.uima.cas.CAS;
 import org.apache.uima.collection.EntityProcessStatus;
 import org.apache.uima.ducc.common.IServiceStatistics;
 import org.apache.uima.ducc.common.TcpStreamHandler;
-import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccProperties;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.util.Level;
@@ -57,7 +56,6 @@ public class UimaAsPing
     int    broker_jmx_port;
     boolean connected;
     UimaAsServiceMonitor monitor;
-    DuccLogger logger = null;
 
     int[] queueSizeWindow;
     int queueCursor = 0;
@@ -65,15 +63,10 @@ public class UimaAsPing
     String nodeIp;
     String pid;
     boolean gmfail = false;
+    boolean enable_log = false;
 
     public UimaAsPing()
     {
-        this.logger = null;
-    }
-
-    public UimaAsPing(DuccLogger logger)
-    {
-        this.logger = logger;
     }
 
     public void init(String args, String ep)
@@ -129,9 +122,11 @@ public class UimaAsPing
             broker_jmx_port = props.getIntProperty("broker_jmx_port", 1099);
             queue_threshold = props.getIntProperty("queue_threshold", 0);
             window = props.getIntProperty("window", 3);
+            enable_log = props.getBooleanProperty("enable_log", false);
+
         }
         queueSizeWindow = new int[window];
-        logger.debug("<ctr>", null, "INIT: meta_timeout", meta_timeout, "broker_jmx_port", broker_jmx_port, "queue_threshold", queue_threshold, "window", window);
+        doLog("<ctr>", null, "INIT: meta_timeout", meta_timeout, "broker_jmx_port", broker_jmx_port, "queue_threshold", queue_threshold, "window", window);
 
         this.monitor = new UimaAsServiceMonitor(endpoint, broker_host, broker_jmx_port);
     }
@@ -141,13 +136,21 @@ public class UimaAsPing
         if ( monitor != null ) monitor.stop();
     }
 
-    private void doLog(String methodName, String msg)
+    private void doLog(String methodName, Object ... msg)
     {
-        if ( logger == null ) {
-            System.out.println(msg);
-        } else {
-            logger.info(methodName, null, msg);
+        if ( ! enable_log ) return;
+
+        StringBuffer buf = new StringBuffer(methodName);
+        for ( Object o : msg ) {
+            buf.append(" ");
+            if ( o == null ) {
+                buf.append("<null>");
+            } else {
+                buf.append(o.toString());
+            }
         }
+        System.out.println(buf);
+
     }
 
     void evaluateBrokerStatistics(IServiceStatistics stats)
@@ -168,7 +171,7 @@ public class UimaAsPing
                 }
                 sum = sum / window;
                 stats.setHealthy( sum < queue_threshold ? true : false );
-                logger.debug(methodName, null, "EVAL: Q depth", monitor.getQueueSize(), "window", sum, "health", stats.isHealthy());
+                doLog(methodName, null, "EVAL: Q depth", monitor.getQueueSize(), "window", sum, "health", stats.isHealthy());
             } else {
                 stats.setHealthy(true);
             }
@@ -230,14 +233,13 @@ public class UimaAsPing
         public void ok()
         {
             // String methodName = "UimaAsPing:get-meta";
-            // logger.info(methodName, null, "Get-Meta received from ", nodeIp, "PID", pid);
             gmfail = false;
         }
 
         public void timeout()
         {
             String methodName = "UimaAsPing:get-meta";
-            logger.info(methodName, null, "Get-Meta timeout from ", nodeIp, "PID", pid);
+            doLog(methodName, null, "Get-Meta timeout from ", nodeIp, "PID", pid);
             gmfail = true;
         }
 
@@ -252,7 +254,7 @@ public class UimaAsPing
         public void onBeforeProcessMeta(String IP, String p)
         {
             String methodName = "UimaAsPing:onBeforeProcessMeta";
-            logger.info(methodName, null, "Get-Meta received from ", IP, ":", p, "for", ep);
+            doLog(methodName, null, "Get-Meta received from ", IP, ":", p, "for", ep);
             pid = p;
             nodeIp = IP;
         }

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsServiceMonitor.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsServiceMonitor.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsServiceMonitor.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/UimaAsServiceMonitor.java Mon Feb  3 19:35:48 2014
@@ -44,7 +44,8 @@ public class UimaAsServiceMonitor
     private QueueViewMBean monitoredQueue;
     private IServiceStatistics qstats;
 
-    double enqueueTime ; 
+
+	double enqueueTime ; 
     long consumerCount ;
     long producerCount ;
     long queueSize     ;
@@ -65,11 +66,6 @@ public class UimaAsServiceMonitor
 
     String jmxFailure = null;
 
-    public long getQueueSize()
-    {
-        return queueSize;
-    }
-
     public UimaAsServiceMonitor(String qname, String broker_host, int broker_port)
     {
         this.qname = qname;
@@ -153,6 +149,22 @@ public class UimaAsServiceMonitor
         stop();
     }
 
+    public void resetStatistics()
+    {
+        try {
+            init(null);
+            
+            if ( monitoredQueue != null ) {
+                monitoredQueue.resetStatistics();
+            }
+            stop();
+        } catch (Throwable t) {
+            // Nothing .. we don't care if this fails; this is just
+            // prophylaxis.  If there is really a problem it will show
+            // up later.
+        }
+    }
+
     public void stop()
     {
         try {
@@ -254,9 +266,106 @@ public class UimaAsServiceMonitor
             expiredCount   = 0;
         }
 
+        monitoredQueue.resetStatistics();
         stop();
     }
 
+    public long getQueueSize()
+    {
+        return queueSize;
+    }
+
+    /**
+	 * @return the enqueueTime
+	 */
+	public double getEnqueueTime() {
+		return enqueueTime;
+	}
+
+	/**
+	 * @return the consumerCount
+	 */
+	public long getConsumerCount() {
+		return consumerCount;
+	}
+
+	/**
+	 * @return the producerCount
+	 */
+	public long getProducerCount() {
+		return producerCount;
+	}
+
+	/**
+	 * @return the minEnqueueTime
+	 */
+	public long getMinEnqueueTime() {
+		return minEnqueueTime;
+	}
+
+	/**
+	 * @return the maxEnqueueTime
+	 */
+	public long getMaxEnqueueTime() {
+		return maxEnqueueTime;
+	}
+
+	/**
+	 * @return the inFlightCount
+	 */
+	public long getInFlightCount() {
+		return inFlightCount;
+	}
+
+	/**
+	 * @return the dequeueCount
+	 */
+	public long getDequeueCount() {
+		return dequeueCount;
+	}
+
+	/**
+	 * @return the enqueueCount
+	 */
+	public long getEnqueueCount() {
+		return enqueueCount;
+	}
+
+	/**
+	 * @return the dispatchCount
+	 */
+	public long getDispatchCount() {
+		return dispatchCount;
+	}
+
+	/**
+	 * @return the expiredCount
+	 */
+	public long getExpiredCount() {
+		return expiredCount;
+	}
+
+	/**
+	 * @return the healthy
+	 */
+	public boolean isHealthy() {
+		return healthy;
+	}
+
+	/**
+	 * @return the gmfail
+	 */
+	public boolean isGmfail() {
+		return gmfail;
+	}
+
+	/**
+	 * @return the jmxFailure
+	 */
+	public String getJmxFailure() {
+		return jmxFailure;
+	}
+
     public static void main(String[] args)
     {
         // System.out.println(args[0] + " " + args[1] + " " + args[2]);

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccProperties.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccProperties.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccProperties.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccProperties.java Mon Feb  3 19:35:48 2014
@@ -135,6 +135,62 @@ public class DuccProperties extends Prop
     }
 
     /**
+     * Get the property, trim junk off the end, and try to convert to double.
+     *
+     * @param The name of the property to look for.
+     *
+     * @throws MissingPropertyException if the property does not exist.
+     * @throws NumberFormattingException if the property cannot be converted to a number.
+     */
+    public double getDoubleProperty(String k)
+    {
+        String v = getProperty(k);
+        if ( v == null ) {
+            throw new MissingPropertyException("Can't find property \"" + k + "\"");
+        }
+        v = trimComments(v);
+        return Double.parseDouble(v);
+    }
+
+    /**
+     * Get the property, trim junk off the end, and try to convert to double.  If the property
+     * cannot be found, return the default instead.
+     *
+     * @param The name of the property to look for.
+     *
+     * @throws MissingPropertyException if the property does not exist.
+     * @throws NumberFormattingException if the property cannot be converted to a number.
+     */
+    public double getDoubleProperty(String k, double dflt)
+    {
+        String v = getProperty(k);
+        if ( v == null ) {
+            return dflt;
+        }
+        v = trimComments(v);
+        return Double.parseDouble(v);
+    }
+
+    /**
+     * Get the property, trim junk off the end, and try to convert to double. If the property
+     * cannot be found, return the default instead.
+     *
+     * @param The name of the property to look for.
+     *
+     * @throws MissingPropertyException if the property does not exist.
+     * @throws NumberFormattingException if the property cannot be converted to a number.
+     */
+    public double getLongProperty(String k, double dflt)
+    {
+        String v = getProperty(k);
+        if ( v == null ) {
+            return dflt;
+        }
+        v = trimComments(v);
+        return Double.parseDouble(v);
+    }
+
+    /**
      * Get the property, trim junk off the end and return it.  If you want the junk, just use getProperty().
      *
      * @param The name of the property to look for.

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_0.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_0.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_0.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_0.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_1.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_1.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_1.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_1.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_2.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_2.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_2.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_2.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_3.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_3.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_3.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_3.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_4.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_4.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_4.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_4.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_5.xml
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_5.xml?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_5.xml (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-examples/src/main/resources/org/apache/uima/ducc/test/service/Service_FixedSleep_5.xml Mon Feb  3 19:35:48 2014
@@ -34,7 +34,7 @@
       <analysisEngine async="false">
         <scaleout numberOfInstances="25"/>
         <asyncPrimitiveErrorConfiguration>
-          <processCasErrors thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
+          <processCasErrors maxRetries="2" timeout="180000" thresholdCount="0" thresholdWindow="0" thresholdAction="terminate"/>
           <collectionProcessCompleteErrors timeout="0" additionalErrorAction="terminate"/>
         </asyncPrimitiveErrorConfiguration>
       </analysisEngine>

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ApiHandler.java Mon Feb  3 19:35:48 2014
@@ -49,6 +49,8 @@ class ApiHandler
     boolean update;
     boolean activate;
 
+    ServiceModifyEvent modifyEvent;
+
     ApiHandler(ServiceUnregisterEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Unregister;
@@ -80,12 +82,15 @@ class ApiHandler
     ApiHandler(ServiceModifyEvent event, ServiceHandler serviceHandler)
     {
         this.cmd = UiOption.Modify;
-        this.friendly = event.getFriendly();
-        this.endpoint = event.getEndpoint();
-        this.instances = event.getInstances();
-        this.autostart = event.getAutostart();
-        this.activate = event.getActivate();
+        this.modifyEvent = (ServiceModifyEvent) event;
         this.serviceHandler = serviceHandler;
+
+        // this.friendly = event.getFriendly();
+        // this.endpoint = event.getEndpoint();
+        // this.instances = event.getInstances();
+        // this.autostart = event.getAutostart();
+        // this.activate = event.getActivate();
+        // this.serviceHandler = serviceHandler;
     }
 
     public void run()
@@ -104,7 +109,8 @@ class ApiHandler
                break;
 
            case Modify:
-               serviceHandler.doModify(friendly, endpoint, instances, autostart, activate);
+               // serviceHandler.doModify(friendly, endpoint, instances, autostart, activate);
+               serviceHandler.doModify(modifyEvent);
                break;
         }
     }

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceMeta.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceMeta.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceMeta.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/IServiceMeta.java Mon Feb  3 19:35:48 2014
@@ -19,6 +19,7 @@
 package org.apache.uima.ducc.sm;
 
 import org.apache.uima.ducc.common.IServiceStatistics;
+import org.apache.uima.ducc.transport.event.sm.IService.ServiceState;
 
 
 
@@ -28,4 +29,5 @@ interface IServiceMeta
     IServiceStatistics getServiceStatistics();
     public void run();
     public void stop();
+    public ServiceState getServiceState();
 }

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java?rev=1564022&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java Mon Feb  3 19:35:48 2014
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.sm;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+/**
+ * This is the packet sent to the external pinger soliciting a response.
+ */
+
+class Ping
+    implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	boolean quit = false;
+    int instances= 0;
+    int references = 0;
+    int runFailures = 0;
+    Properties smState;
+
+    public Ping(boolean quit, Properties props)
+    {
+        this.quit = quit;
+        this.smState = props;
+    }
+
+    public Ping(boolean quit, int instances, int references, int runFailures)
+    {
+        this.quit = quit;
+        this.instances= instances;
+        this.references = references;
+        this.runFailures = runFailures;
+    }
+
+    public boolean isQuit()          { return quit; }
+    public int     getInstances()    { return instances; }
+    public int     getReferences()   { return references; }
+    public int     getRunFailures()  { return runFailures; }
+    public Properties getSmState  () { return smState; }
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Ping.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingDriver.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingDriver.java?rev=1564022&r1=1564021&r2=1564022&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingDriver.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingDriver.java Mon Feb  3 19:35:48 2014
@@ -19,20 +19,28 @@
 package org.apache.uima.ducc.sm;
 
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.ArrayList;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
 
 import org.apache.uima.ducc.cli.AServicePing;
-import org.apache.uima.ducc.cli.UimaAsPing;
 import org.apache.uima.ducc.common.IServiceStatistics;
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccProperties;
+import org.apache.uima.ducc.transport.event.common.IDuccState.JobState;
 
 
 /**
@@ -82,10 +90,9 @@ class PingDriver
 
     int meta_ping_rate;              // ducc.properties configured ping rate
     int meta_ping_stability;         // ducc.properties number of missed pings before setting service unresponive
-    String meta_ping_timeout;        // job.properties configured time to wait for ping to return in ms
+    long meta_ping_timeout;          // how long we wait for pinger to return when requesing a ping
     Thread ping_thread;              // thread to manage external process pingers
     boolean internal_ping = true;    // if true, use default UIMA-AS pinger in thread inside SM propert
-    AServicePing internal_pinger = null; // pinger used if internal_ping is true
 
     IServiceStatistics service_statistics = null;
 
@@ -95,7 +102,10 @@ class PingDriver
     boolean do_log = true;
 
     boolean shutdown = false;
+    PingStopper pingStopper = null;
+    Timer timer = null;
     
+    ServiceState pingState = ServiceState.Waiting;
     
     PingDriver(ServiceSet sset)
     {        
@@ -103,31 +113,112 @@ class PingDriver
         DuccProperties job_props = sset.getJobProperties();
         DuccProperties meta_props = sset.getMetaProperties();
 
+        // establish the default pinger, then see if another pinger is specified and set it.        
+        this.ping_class        = System.getProperty("ducc.sm.default.monitor.class", "org.apache.uima.ducc.cli.UimaAsPing");
+        this.ping_class        = job_props.getStringProperty("service_ping_class", this.ping_class);
+
+        // If the pinger is registered with us we can pick up (and trust) the registered defaults.  Read the registration now.
+        DuccProperties ping_props = findRegisteredPinger(this.ping_class);
+        if ( ping_props == null ) {          // this is an internal or system error of some sort
+            throw new IllegalStateException("Cannot start pinger.");
+        } else {
+            this.internal_ping = ping_props.getBooleanProperty("internal", false);
+
+            // One more resolution, in case the class name is actually the name of a registered pinger
+            String real_class  = ping_props.getProperty("service_ping_class");
+            if ( real_class != null ) {
+                this.ping_class = real_class;
+            }
+            logger.info("<ctr>", sset.getId(), "Using ping class", this.ping_class); 
+        }
+        
         this.endpoint          = meta_props.getStringProperty("endpoint");
         this.user              = meta_props.getStringProperty("user");
-        String jvm_args_str    = job_props.getStringProperty("service_ping_jvm_args", "");
-        this.ping_class        = job_props.getStringProperty("service_ping_class", null);
-        this.ping_arguments    = job_props.getStringProperty("service_ping_arguments", null);
+
+        this.ping_arguments    = resolveStringProperty("service_ping_arguments", ping_props, job_props, null);
+        String jvm_args_str    = resolveStringProperty("service_ping_jvm_args" , ping_props, job_props, "");
         
-        if ( (ping_class == null) || ping_class.equals(UimaAsPing.class.getName()) ) {
-            internal_ping = true;
-        } else {
-            internal_ping = false;
-            this.meta_ping_timeout = job_props.getStringProperty("service_ping_timeout");
-            this.do_log            = job_props.getBooleanProperty("service_ping_dolog", true);
-            this.classpath         = job_props.getStringProperty("service_ping_classpath", System.getProperty("java.class.path"));
-            this.working_directory = job_props.getStringProperty("working_directory");
-            this.log_directory     = job_props.getStringProperty("log_directory");
-        }
+        this.meta_ping_timeout = resolveIntProperty    ("service_ping_timeout", ping_props, job_props, ServiceManagerComponent.meta_ping_timeout);
+        this.do_log            = resolveBooleanProperty("service_ping_dolog", ping_props, job_props, false);
+        this.classpath         = resolveStringProperty ("service_ping_classpath", ping_props, job_props, System.getProperty("java.class.path"));
+        this.working_directory = resolveStringProperty ("working_directory", ping_props, job_props, null); // cli always puts this int job props, no default 
+
+        this.log_directory     = resolveStringProperty ("log_directory", ping_props, job_props, null);     // cli always puts this int job props, no default 
 
-        jvm_args_str = jvm_args_str + " -Dducc.sm.meta.ping.timeout=" + meta_ping_timeout;
         jvm_args_str = jvm_args_str.trim();
-        jvm_args = jvm_args_str.split("\\s+");
+        if ( jvm_args_str.equals("") ) {
+            jvm_args = null;
+        } else {
+            jvm_args = jvm_args_str.split("\\s+");
+        }
 
-        this.meta_ping_rate = ServiceManagerComponent.meta_ping_rate;
+        // global, not customizable per-pinger
+        this.meta_ping_rate      = ServiceManagerComponent.meta_ping_rate;
         this.meta_ping_stability = ServiceManagerComponent.meta_ping_stability;
     }
 
+    //
+    // If the class is registered, read it into ducc properties and return it.  Else return an
+    // empty ducc properties.  The resolver will deal with the emptiness.
+    //
+    protected DuccProperties findRegisteredPinger(String cls)
+    {
+    	String methodName = "find RegisteredPinger";
+        DuccProperties answer = new DuccProperties();
+        File f = new File(System.getProperty("DUCC_HOME") + "/resources/service_monitors/" + cls);
+        if ( f.exists () ) {
+            try {
+				answer.load(f.getCanonicalPath());
+                logger.info(methodName, sset.getId(), "Loading site-registered service monitor from", cls);
+			} catch (Exception e) {
+                logger.error(methodName, sset.getId(), "Cannot load site-registered service monitor", f.getName(), e);
+                return null;
+			}
+        }
+        return answer;        
+    }
+
+    // this resolves the prop in either of the two props files and expands ${} against System props, which include
+    // everything in ducc.properties
+    protected String resolveStringProperty(String prop, DuccProperties ping_props, DuccProperties job_props, String deflt)
+    {
+        if ( internal_ping ) {
+            // internal ping only gets to adjust the ping tuning parameters
+            if ( ! prop.equals("service_ping_arguments") ) return ping_props.getStringProperty(prop, deflt);
+        } 
+
+        prop = prop.trim();
+        //
+        // Search order: first,  what is registered to the service, 
+        //               second, what is registered to the site-registered pinger
+        //               third,  the passed-in default
+        //
+        String val = job_props.getProperty(prop);
+        if ( val == null ) {
+            val = ping_props.getProperty(prop);
+        }
+
+        if ( val == null ) {
+            val = deflt;
+        }
+
+        if ( val != null ) val = val.trim();
+        return val;
+    }
+
+    protected int resolveIntProperty(String prop, DuccProperties ping_props, DuccProperties job_props, int deflt)
+    {
+        String val = resolveStringProperty(prop, ping_props, job_props, null);
+        return (val == null ? deflt : Integer.parseInt(val));
+    }
+
+    protected boolean resolveBooleanProperty(String prop, DuccProperties ping_props, DuccProperties job_props, boolean deflt)
+    {
+        String val = resolveStringProperty(prop, ping_props, job_props, Boolean.toString(deflt));
+        return ( val.equalsIgnoreCase("t") ||             // must be t T true TRUE - all else is false
+                 val.equalsIgnoreCase("true") );
+    }
+
     /**
      * Test from main only
      */
@@ -149,6 +240,44 @@ class PingDriver
         this.test_mode = true;
     }
 
+
+    /**
+     * Used by the ServiceSet state machine.
+     */
+    public ServiceState getServiceState()
+    {
+        return this.pingState;
+    }
+
+    /**
+     * Used by the ServiceSet state machine for messages
+     */
+    public long getId()
+    {
+        return 0;
+    }
+
+    public JobState getState()
+    {
+    	String methodName = "getState";
+        switch ( pingState ) {
+            case Available:
+                return JobState.Running;
+            case Stopped:
+                return JobState.Completed;
+            case Waiting:
+                return JobState.Initializing;  // not really, but not used. don't have or need a better alternative.
+            default:
+                logger.error(methodName, sset.getId(), "Unexpected state in Ping driver:", pingState);
+                return JobState.Completed;
+        }
+    }
+
+    public void setState(JobState s) 
+    {
+        // nothing
+    }
+
     public IServiceStatistics getServiceStatistics()
     {
         return service_statistics;
@@ -178,72 +307,148 @@ class PingDriver
 
     }
 
-    void handleStatistics(IServiceStatistics stats)
+    void handleResponse(Pong response)
     {
         String methodName = "handleStatistics";
 
-        this.service_statistics = stats;
-        if ( stats == null ) {
+        this.service_statistics = response.getStatistics();
+        if ( service_statistics == null ) {
             logger.error(methodName, sset.getId(), "Service statics are null!");
             errors++;
         } else {
             if ( service_statistics.isAlive() ) {
-                synchronized(this) {
-                    sset.setResponsive();
-                }
-                logger.info(methodName, sset.getId(), "Ping ok: ", endpoint, stats.toString());
+                pingState = ServiceState.Available;
+                logger.info(methodName, sset.getId(), "Ping ok: ", endpoint, service_statistics.toString());
                 missed_pings = 0;
             } else {
-                logger.error(methodName, sset.getId(), "Missed_pings ", ++missed_pings, "endpoint", endpoint, stats.toString());
+                logger.error(methodName, sset.getId(), "Missed_pings ", ++missed_pings, "endpoint", endpoint, service_statistics.toString());
                 if ( missed_pings > meta_ping_stability ) {
-                    sset.setUnresponsive();
-                    logger.info(methodName, sset.getId(), "Seting state to unresponsive, endpoint",endpoint);
-                } else if ( missed_pings > (meta_ping_stability / 2) ) {
-                    sset.setWaiting();
-                    logger.info(methodName, sset.getId(), "Seting state to waiting, endpoint,", endpoint);
-                }                
+                    pingState = ServiceState.Waiting;
+                }
             }
         }
-
+        
+        sset.signalRebalance(response.getAdditions(), response.getDeletions(), response.isExcessiveFailures());
     }
+    
+    AServicePing loadInternalMonitor()
+     	throws ClassNotFoundException,
+                IllegalAccessException,
+                InstantiationException,
+                MalformedURLException
+    {
+        if ( classpath == null ) {
+            @SuppressWarnings("unchecked")
+			Class<AServicePing> cl = (Class<AServicePing>) Class.forName(ping_class);
+            return (AServicePing) cl.newInstance();
+        } else {
+             String[] cp_elems = classpath.split(":");
+             URL[]    cp_urls = new URL[cp_elems.length];
+            
+             for ( int i = 0; i < cp_elems.length; i++ ) {
+                 cp_urls[i] = new URL("file://" + cp_elems[i]);                
+             }
+             @SuppressWarnings("resource")
+			URLClassLoader l = new URLClassLoader(cp_urls);
+             @SuppressWarnings("rawtypes")
+			Class loaded_class = l.loadClass(ping_class);
+             l = null;
+             return (AServicePing) loaded_class.newInstance();
+        }
+        }
 
-    public void runAsThread()
+    void runAsThread()
     {
-    	String methodName = "runAsThread";
-        internal_pinger = new UimaAsPing(logger);
+        long tid = Thread.currentThread().getId();
+
+    	String methodName = "runAsThread[" + tid + "]";
+        AServicePing pinger = null;
+        Properties props = new Properties();
+
+		try {
+			pinger = loadInternalMonitor();
+		} catch (ClassNotFoundException e1) {
+            logger.error(methodName, sset.getId(), "Cannot load pinger: ClassNotFoundException(", ping_class, ")");
+            return;
+		} catch (IllegalAccessException e1) {
+            logger.error(methodName, sset.getId(), "Cannot load pinger: IllegalAccessException(", ping_class, ")");
+            return;
+		} catch (InstantiationException e1) {
+            logger.error(methodName, sset.getId(), "Cannot load pinger: InstantiationException(", ping_class, ")");
+            return;
+		} catch ( MalformedURLException e1) {
+            logger.error(methodName, sset.getId(), "Cannot load pinger: Cannot form URLs from classpath entries(", ping_class, ")");
+            return;		
+		}
+
         try {
-            internal_pinger.init(ping_arguments, endpoint);
+            pinger.init(ping_arguments, endpoint);
+            props.setProperty("total-instances", "" + sset.countImplementors());
+            props.setProperty("active-instances", "" + sset.getActiveInstances());
+            props.setProperty("references", "" + sset.countReferences());
+            props.setProperty("runfailures", "" + sset.getRunFailures());
+
+            pinger.setSmState(props);
+            while ( ! shutdown ) {
+                
+                Pong pr = new Pong();
+
+                pr.setStatistics(pinger.getStatistics());
+                pr.setAdditions (pinger.getAdditions());
+                pr.setDeletions (pinger.getDeletions());
+                pr.setExcessiveFailures(pinger.isExcessiveFailures());
+
+                handleResponse(pr);
+                if ( errors > error_threshold ) {
+                    pinger.stop();
+                    logger.warn(methodName, sset.getId(), "Ping exited because of excess errors: ", errors);
+                    break;
+                }
+                
+                try {
+                    Thread.sleep(meta_ping_rate);
+                } catch (InterruptedException e) {
+                    // nothing, if we were shutdown we'll exit anyway, otherwise who cares
+                }                
+            }
         } catch ( Throwable t ) {
             logger.warn(methodName, sset.getId(), t);
-            sset.pingExited();
-        }
-        while ( ! shutdown ) {
-            
-            handleStatistics(internal_pinger.getStatistics());
-            if ( errors > error_threshold ) {
-                internal_pinger.stop();
-                logger.warn(methodName, sset.getId(), "Ping exited because of excess errors: ", errors);
-                sset.pingExited();
-            }
-            
-            try {
-				Thread.sleep(meta_ping_rate);
-			} catch (InterruptedException e) {
-                // nothing, if we were shutdown we'll exit anyway, otherwise who cares
-			}
-            
         }
+
+        pinger = null;
+        sset.pingExited(errors, this);
     }
 
     public void runAsProcess() 
     {
-        String methodName = "run";
+        long tid = Thread.currentThread().getId();
+        String methodName = "runAsProcess[" + tid + "]";
+
+        String cp = classpath;
+        String dh = System.getProperty("DUCC_HOME");
+
+        // we need the sm jar and the cli jar ... dig around in the runtime to try to find them
+        File libdir = new File(dh + "/lib/uima-ducc");
+        String[] jars = libdir.list();
+        for ( String j : jars ) {
+            if ( j.contains("ducc-sm") ) {
+                cp = cp + ":" + dh + "/lib/uima-ducc/" + j;
+                continue;
+            }
+            if ( j.contains("ducc-cli") ) {
+                cp = cp + ":" + dh + "/lib/uima-ducc/" + j;
+                continue;
+            }
+
+        }
+        //cp = cp + ":" + dh + "/lib/uima-ducc/ducc-sm.jar";
+        //''cp = cp + ":" + dh + "/lib/uima-ducc/uima-ducc-cli-1.0.0-SNAPSHOT.jar";
 
         try {
             pinger =  new PingThread();
         } catch ( Throwable t ) {
             logger.error(methodName, sset.getId(), "Cannot start listen socket, pinger not started.", t);
-            sset.setUnresponsive();
+            pingState = ServiceState.Stopped;
             return;
         }
         int port = pinger.getPort();
@@ -266,29 +471,32 @@ class PingDriver
         }
 
         arglist.add(System.getProperty("ducc.jvm"));
-        for ( String s : jvm_args) {
-            arglist.add(s);
+        if ( jvm_args != null ) {
+            for ( String s : jvm_args) {
+                arglist.add(s);
+            }
         }
         arglist.add("-cp");
-        arglist.add(System.getProperty("java.class.path") + ":" + classpath);
-        arglist.add("org.apache.uima.ducc.sm.ServicePingMain");
+        arglist.add(cp);
+        //arglist.add("-Xmx100M");
+        arglist.add("-Dcom.sun.management.jmxremote");
+        arglist.add("org.apache.uima.ducc.smnew.ServicePingMain");
         arglist.add("--class");
         arglist.add(ping_class);
         arglist.add("--endpoint");
         arglist.add(endpoint);
         arglist.add("--port");
+        arglist.add(Integer.toString(port));
+
         if( ping_arguments != null ) {
             arglist.add("--arguments");
             arglist.add(ping_arguments);
         }
-
-        arglist.add(Integer.toString(port));
         
         int i = 0;
         for ( String s : arglist) {
             logger.debug(methodName, sset.getId(), "Args[", i++,"]:  ", s);
         }
-
         ProcessBuilder pb = new ProcessBuilder(arglist);
         
         //
@@ -309,7 +517,7 @@ class PingDriver
             sel.start();
         } catch (Throwable t) {
             logger.error(methodName, sset.getId(), "Cannot establish ping process:", t);
-            sset.setUnresponsive();
+            pingState = ServiceState.Stopped;
             return;
         }
         
@@ -317,15 +525,23 @@ class PingDriver
         while ( true ) {
             try {
                 rc = ping_main.waitFor();
-                logger.debug(methodName, sset.getId(), "Pinger returns rc ", rc);
-                sset.pingExited();
+                ping_main = null;
+
+                if ( pingStopper != null ) {
+                    pingStopper.cancel();
+                    pingStopper = null;
+                    logger.info(methodName, sset.getId(), "Pinger returned, pingStopper is canceled.");
+                }
+
+                logger.info(methodName, sset.getId(), "Pinger returns rc ", rc);
+                sset.pingExited(rc, this);
                 break;
             } catch (InterruptedException e2) {
                 // nothing
             }
         }
 		
-		pinger.stop();
+		// pinger.stop();
         sin_listener.stop();
         ser_listener.stop();
     }
@@ -334,13 +550,34 @@ class PingDriver
     {
         shutdown = true;
         if ( !internal_ping ) {
-            if ( pinger       != null ) pinger.stop();
-            if ( sin_listener != null ) sin_listener.stop();
-            if ( ser_listener != null ) ser_listener.stop();
-            if ( ping_main    != null ) ping_main.destroy();
+            if ( pinger != null ) pinger.stop();
+            pingStopper = new PingStopper();
+
+            if ( timer == null ) {
+                timer = new Timer();
+            }
+            timer.schedule(pingStopper, 60000);
+        }
+    }
+
+    private class PingStopper
+        extends TimerTask
+    {
+        PingStopper()
+        {        
+            String methodName = "PingStopper.init";
+            logger.debug(methodName, sset.getId(), "Wait for pinger to exit:", 60000);
+        }
+
+        public void run()
+        {
+            String methodName = "PingStopper.run";
+            logger.debug(methodName, sset.getId(), "PingStopper kills reluctant pinger");
+            if ( ping_main != null )  ping_main.destroy();
         }
     }
 
+
     class PingThread
         implements Runnable
     {
@@ -362,73 +599,92 @@ class PingDriver
 
         synchronized void stop()
         {
+        	String methodName = "stop";
+            logger.info(methodName, sset.getId(), "Pinger stopping: set done = true");
             this.done = true;
         }
 
         public void run()
         {
-        	String methodName = "PingThread.run()";
-            try {
+            long tid = Thread.currentThread().getId();
+        	String methodName = "XtrnPingThread.run[" + tid + "]";
+        	try {
 
                 Socket sock = server.accept();
                 // Socket sock = new Socket("localhost", port);
-                sock.setSoTimeout(5000);
-                OutputStream out = sock.getOutputStream();
+                sock.setSoTimeout(meta_ping_rate);                     // don't timout faster than ping rate
+                OutputStream outs = sock.getOutputStream();
                 InputStream  in =  sock.getInputStream();
                 ObjectInputStream ois = new ObjectInputStream(in);
-                
+                ObjectOutputStream oos = new ObjectOutputStream(outs);
+                Properties props = new Properties();
+
                 ping_ok = false;         // we expect the callback to change this
 				while ( true ) {
                     synchronized(this) {
                         if ( done ) {
                             // Ask for the ping
                             try {
-                                logger.trace(methodName, sset.getId(), "PingDriver: ping QUIT");
-                                out.write('Q');
-                                out.flush();
+                                logger.info(methodName, sset.getId(), "ExtrnPingDriver: send QUIT to pinger.");
+                                oos.writeObject(new Ping(true, props));
+                                oos.flush();
+                                //oos.reset();
                             } catch (IOException e1) {
                                 logger.error(methodName, sset.getId(), e1);
-                                errors++;
                             }
-                            ois.close();
-                            out.close();
-                            in.close();                            
+                            logger.info(methodName, sset.getId(), "ExtrnPingDriver: QUIT is sent and flushed; thread exits.");
+                            // gc will close all the descriptors and handles
+                            //ois.close();
+                            //oos.close();
+                            //in.close();                            
+                            //sock.close();
                             return;
                         }
                     }
 
-                    if ( errors > error_threshold ) {
-                        stop();
-                    }
-
                     // Ask for the ping
                     try {
-                        logger.trace(methodName, sset.getId(), "PingDriver: ping OUT");
-                        out.write('P');
-                        out.flush();
+                        logger.info(methodName, sset.getId(), "ExtrnPingDriver: ping OUT");
+                        props.setProperty("total-instances", "" + sset.countImplementors());
+                        props.setProperty("active-instances", "" + sset.getActiveInstances());
+                        props.setProperty("references", "" + sset.countReferences());
+                        props.setProperty("runfailures", "" + sset.getRunFailures());
+                        oos.writeObject(new Ping(false, props));
+                        oos.flush();
+                        oos.reset();
                     } catch (IOException e1) {
                         logger.error(methodName, sset.getId(), e1);
                         errors++;
+                        return;
                     }
                     
                     // Try to read the response
-                    handleStatistics((IServiceStatistics) ois.readObject());
+                    try {
+                        Pong resp = (Pong) ois.readObject();
+                        logger.info(methodName, sset.getId(), "ExtrnPingDriver: ping RECEIVED");
+                        handleResponse(resp);
+                        logger.info(methodName, sset.getId(), "ExtrnPingDriver: ping HANDLED");
+                    } catch (IOException e1) {
+                        logger.warn(methodName, sset.getId(), "ExtrnPingDriver: Error receiving ping:", e1);
+                        errors++;
+                        return;
+                    }
 
                     // Wait a bit for the next one
                     try {
-                        // logger.info(methodName, sset.getId(), "SLEEPING", my_ping_rate, "ms", sset.toString());
+                        logger.info(methodName, sset.getId(), "ExtrnPingDriver: SLEEPING", meta_ping_rate, "ms", sset.toString());
                         Thread.sleep(meta_ping_rate);
-                        // logger.info(methodName, sset.getId(), "SLEEP returns", sset.toString());
+                        logger.info(methodName, sset.getId(), "ExtrnPingDriver: SLEEP returns", sset.toString());
                     } catch (InterruptedException e) {
-                        // nothing
+                        logger.info(methodName, sset.getId(), e);
                     }
 
                 }
 			} catch (IOException e) {
-                logger.error(methodName, sset.getId(), "Error receiving ping", e);
+                logger.error(methodName, sset.getId(), "ExtrnPingDriver: Error receiving ping", e);
                 errors++;
 			} catch (ClassNotFoundException e) {
-                logger.error(methodName, sset.getId(), "Input garbled:", e);
+                logger.error(methodName, sset.getId(), "ExtrnPingDriver: Input garbled:", e);
                 errors++;
 			}
         }       
@@ -458,7 +714,8 @@ class PingDriver
         public void run()
         {
             if ( done ) return;
-            String methodName = "StdioListener.run";
+            long tid = Thread.currentThread().getId();
+            String methodName = "StdioListener.run[" + tid + "]";
 
             BufferedReader br = new BufferedReader(new InputStreamReader(in));
             while ( true ) {

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java?rev=1564022&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java Mon Feb  3 19:35:48 2014
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.sm;
+
+import org.apache.uima.ducc.common.utils.DuccLogger;
+import org.apache.uima.ducc.common.utils.DuccProperties;
+import org.apache.uima.ducc.common.utils.SystemPropertyResolver;
+import org.apache.uima.ducc.transport.event.common.IDuccState.JobState;
+
+/**
+* Represent a single instance.  
+*
+* This is a simple class, mostly just a container for the state machine.
+*/
+@SuppressWarnings("serial")
+class PingOnlyServiceInstance
+    extends ServiceInstance
+{
+	private DuccLogger logger = DuccLogger.getLogger(this.getClass().getName(), COMPONENT_NAME);	
+	private PingOnlyDriver driver = null;
+	private PingOnlyServiceInstance me;
+	
+    PingOnlyServiceInstance(ServiceSet sset)
+    {
+    	super(sset);
+    	me = this;
+    }
+
+//     void setState(DuccWorkJob dwj)
+//     {
+//         this.state = dwj.getJobState();
+//     }
+
+    long start(String spec, DuccProperties meta_props)
+    {
+    	String methodName = "start";
+
+        // ping-only, we have no idea what the state of the remote service is, so we assume
+        // it is running.  If not the ping will fail anyway, preventing dependent jobs from
+        // using it.
+        logger.info(methodName, sset.getId(), "START PING-ONLY INSTANCE");
+        state = JobState.Running;
+        setStopped(false);
+        driver = new PingOnlyDriver();
+        Thread driver_thread = new Thread(driver);
+        driver_thread.start();
+        return numeric_id;
+    }
+
+
+    /**
+     * This assumes the caller has already verified that I'm a registered service.
+     */
+    void stop()
+    {
+        String methodName = "stop";
+        logger.info(methodName, sset.getId(), "STOP PING-ONLY INSTANCE");
+        state = JobState.Completed;
+        driver.stop();
+        setStopped(true);
+    }
+
+    /**
+     * Must simulate state being driven in from the OR
+     */
+    class PingOnlyDriver 
+        implements Runnable
+    {
+        boolean stopped = false;
+
+        public synchronized void stop()
+        {
+            this.stopped = true;
+        }
+
+        public void run()
+        {
+        	String methodName = "PingOnlyDriver.run()";
+            int delay = SystemPropertyResolver.getIntProperty("ducc.orchestrator.state.publish.rate", 30000);
+            
+            while ( true ) {
+                if (stopped) return;
+
+                try {
+                    logger.info(methodName, sset.getId(), "Starts Wait of", delay);
+					Thread.sleep(delay);
+                    //logger.info(methodName, sset.getId(), "Returns");
+				} catch (InterruptedException e) {
+					// nothing
+				}
+                sset.signal(me);
+            }
+        }
+
+        
+    }
+
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/PingOnlyServiceInstance.java
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java?rev=1564022&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java Mon Feb  3 19:35:48 2014
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.sm;
+
+import java.io.Serializable;
+
+import org.apache.uima.ducc.common.IServiceStatistics;
+
+/**
+ * Internal (to SM) object for returning ping responses.
+ */
+public class Pong
+    implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+	IServiceStatistics statistics;
+    int additions;
+    int deletions;
+    boolean excessiveFailures = false;
+
+    public Pong()
+    {
+    }
+
+    public IServiceStatistics getStatistics() 
+    {
+		return statistics;
+	}
+
+    public void setStatistics(IServiceStatistics statistics) 
+    {
+		this.statistics = statistics;
+	}
+
+	public int getAdditions() 
+    {
+		return additions;
+	}
+    
+	public void setAdditions(int additions) 
+    {
+		this.additions = additions;
+	}
+    
+	public int getDeletions() 
+    {
+		return deletions;
+	}
+    
+	public void setDeletions(int deletions) 
+    {
+		this.deletions = deletions;
+	}
+
+    public void setExcessiveFailures(boolean er)
+    {
+        this.excessiveFailures = er;
+    }
+    
+    public boolean isExcessiveFailures()
+    {
+    	return this.excessiveFailures;
+    }
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/Pong.java
------------------------------------------------------------------------------
    svn:executable = *