Author: challngr
Date: Sun Apr 13 16:05:35 2014
New Revision: 1587023

URL: http://svn.apache.org/r1587023
Log:
UIMA-3742 Use rename/create/remove logic to safely store service state files.

Modified:
    
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java

Modified: 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
URL: 
http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java?rev=1587023&r1=1587022&r2=1587023&view=diff
==============================================================================
--- 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
 (original)
+++ 
uima/sandbox/uima-ducc/trunk/uima-ducc-sm/src/main/java/org/apache/uima/ducc/sm/ServiceSet.java
 Sun Apr 13 16:05:35 2014
@@ -18,6 +18,7 @@
 */
 package org.apache.uima.ducc.sm;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -125,10 +126,18 @@ public class ServiceSet
     IServiceMeta serviceMeta = null;
 
     // registered services state files
-    DuccProperties job_props  = null;
-    DuccProperties meta_props = null;
+    private DuccProperties job_props  = null;
     String props_filename = null;
+    String props_filename_temp = null;
+    File props_file;
+    File props_file_temp;
+
+    private DuccProperties meta_props = null;
+
     String meta_filename = null;
+    String meta_filename_temp = null;
+    File meta_file;
+    File meta_file_temp;
     boolean deregistered = false;
 
     ServiceType  service_type  = ServiceType.Undefined;
@@ -161,8 +170,17 @@ public class ServiceSet
         this.job_props = props;
         this.meta_props = meta;
         this.id = id;
+
         this.props_filename = props_filename;
+        this.props_filename_temp = props_filename + ".tmp";
+        this.props_file = new File(props_filename);
+        this.props_file_temp = new File(props_filename_temp);
+
         this.meta_filename = meta_filename;
+        this.meta_filename_temp = meta_filename + ".tmp";
+        this.meta_file = new File(meta_filename);
+        this.meta_file_temp = new File(meta_filename_temp);
+
         this.service_state = ServiceState.Stopped;
         this.linger_time = 
props.getLongProperty(UiOption.ServiceLinger.pname(), linger_time);
         this.key = meta.getProperty("endpoint");
@@ -468,8 +486,10 @@ public class ServiceSet
          
          // could have more implementors than instances if some were started 
dynamically but the count not persisted
          int needed = Math.max(0, instances - countImplementors());
-         logger.info(methodName, id, "Autostarting", needed, "instance" + 
((needed > 1) ? "s" : ""), "already have", countImplementors());
-         start(needed);
+         if ( needed > 0 ) {
+             logger.info(methodName, id, "Autostarting", needed, "instance" + 
((needed > 1) ? "s" : ""), "already have", countImplementors());
+             start(needed);
+         }
     }
 
 
@@ -650,10 +670,47 @@ public class ServiceSet
         return registered_instances;
     }
 
+    private void saveProperties(DuccProperties props, File pfile, File 
pfile_tmp, String type)
+    {
+       
+       String methodName = "saveMetaProperties";
+        FileOutputStream fos = null;
+        try {
+            if ( (!pfile.exists()) || pfile.renameTo(pfile_tmp) ) {
+                fos = new FileOutputStream(pfile);
+                props.store(fos, type + " Descriptor");
+            } else {
+                logger.warn(methodName, id, "Cannot save", type, "properties, 
rename of", pfile, "to", pfile_tmp, "fails.");
+                if ( (!pfile.exists()) && pfile_tmp.exists() ) {
+                    if ( !pfile_tmp.renameTo(pfile) ) {
+                        logger.error(methodName, id, "Cannot restore", 
pfile_tmp, "to", pfile, "after failed update.");
+                    }
+                }
+            }
+               } catch (FileNotFoundException e) {
+            logger.warn(methodName, id, "Cannot save", type, "properties, file 
does not exist.");
+               } catch (IOException e) {
+            logger.warn(methodName, id, "I/O Error saving", type, "service 
properties:", e);
+               } finally {
+            try {
+                               if ( fos != null ) fos.close();
+                pfile_tmp.delete();
+                       } catch (IOException e) {
+                logger.error(methodName, id, "Cannot close", type, 
"properties:", e);
+                       }
+        }
+    }
+
     synchronized void saveMetaProperties()
     {
         String methodName = "saveMetaProperties";
-
+        
+        try {
+            throw new IllegalStateException("Saving meta properties");
+        } catch ( Throwable t) {
+            t.printStackTrace();
+        }
+        
         if ( isDeregistered() ) return;
 
         if ( meta_filename == null ) {
@@ -690,44 +747,15 @@ public class ServiceSet
                 meta_props.put("service-statistics", "" + ss.getInfo());
             }
         }
-        
-        FileOutputStream fos = null;
-        try {            
-                       fos = new FileOutputStream(meta_filename);            
-                       meta_props.store(fos, "Meta descriptor");
-               } catch (FileNotFoundException e) {
-            if ( !isDeregistered() ) {
-                logger.warn(methodName, id, "Cannot save meta properties, file 
does not exist.");
-            }
-               } catch (IOException e) {
-            logger.warn(methodName, id, "I/O Error saving meta properties:", 
e);
-               } finally {
-            try {
-                               if ( fos != null ) fos.close();
-                       } catch (IOException e) {
-                       }
-        }
+
+        saveProperties(meta_props, meta_file, meta_file_temp, "Meta");
+                
         return;
     }
 
     void saveServiceProperties()
     {
-        String methodName = "saveServiceProperties";
-        FileOutputStream fos = null;
-        try {
-               fos = new FileOutputStream(props_filename);
-                       job_props.store(fos, "Service descriptor");
-               } catch (FileNotFoundException e) {
-            logger.warn(methodName, id, "Cannot save service properties, file 
does not exist.");
-               } catch (IOException e) {
-            logger.warn(methodName, id, "I/O Error saving service 
properties:", e);
-               } finally {
-            try {
-                               if ( fos != null ) fos.close();
-                       } catch (IOException e) {
-                       }
-        }
-        return;
+        saveProperties(job_props, props_file, props_file_temp, "Service");
     }
 
     synchronized void updateInstance(long iid, long share_id, String host)
@@ -988,6 +1016,7 @@ public class ServiceSet
 
             break;   // required break
         }
+        saveMetaProperties();
     }
 
     /**
@@ -1189,8 +1218,8 @@ public class ServiceSet
         this.service_state = new_state;
         if ( prev != new_state ) {
             logger.info(methodName, id, "State update from[" + prev + "] to[" 
+ new_state + "] via[" + cumulative + "] Inst[" + tail + "]" );
+            saveMetaProperties();
         }
-        saveMetaProperties();
 
         // Execute actions that must always occur based on the new state
         // These are all idempotent actions, call them as often as you want 
and no harm.


Reply via email to