You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mi...@apache.org on 2009/03/13 21:37:52 UTC

svn commit: r753390 - in /ode/trunk: axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java utils/src/main/java/org/apache/ode/utils/WatchDog.java

Author: midon
Date: Fri Mar 13 20:37:33 2009
New Revision: 753390

URL: http://svn.apache.org/viewvc?rev=753390&view=rev
Log:
ODE-549: lock for watchdog

Modified:
    ode/trunk/axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java
    ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
    ode/trunk/utils/src/main/java/org/apache/ode/utils/WatchDog.java

Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java?rev=753390&r1=753389&r2=753390&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/soapbinding/SoapExternalService.java Fri Mar 13 20:37:33 2009
@@ -224,9 +224,9 @@
             serviceClient = new ServiceClient(_configContext, null);
             _cachedClients.set(serviceClient);
         }
-        AxisService anonymousService = _axisServiceWatchDog.getObserver().anonymousService;
+        AxisService anonymousService = _axisServiceWatchDog.getObserver().get();
         serviceClient.setAxisService(anonymousService);
-        serviceClient.setOptions(_axisOptionsWatchDog.getObserver().options);
+        serviceClient.setOptions(_axisOptionsWatchDog.getObserver().get());
 
         applySecuritySettings(serviceClient);
 
@@ -397,31 +397,26 @@
      * The {@link org.apache.axis2.client.ServiceClient} instance is created from the main Axis2 config instance and
      * this service-specific config file.
      */
-    private class ServiceFileObserver extends WatchDog.DefaultObserver {
-        String serviceName = "anonymous_service_" + new GUID().toString();
-        AxisService anonymousService;
+    private class ServiceFileObserver extends WatchDog.DefaultObserver<AxisService> {
+        String serviceName = "axis_service_for_" + _serviceName + "#" + _portName + "_" + new GUID().toString();
         File file;
 
         private ServiceFileObserver(File file) {
             this.file = file;
         }
 
-        public boolean isInitialized() {
-            return anonymousService != null;
-        }
-
         public void init() {
-            // create an anonymous axis service that will be used by the ServiceClient
+// create an anonymous axis service that will be used by the ServiceClient
             // this service will be added to the AxisConfig so do not reuse the name of the external service
             // as it could blow up if the service is deployed in the same axis2 instance
-            anonymousService = new AxisService(serviceName);
-            anonymousService.setParent(_axisConfig);
+            object = new AxisService(serviceName);
+            object.setParent(_axisConfig);
 
             OutOnlyAxisOperation outOnlyOperation = new OutOnlyAxisOperation(ServiceClient.ANON_OUT_ONLY_OP);
-            anonymousService.addOperation(outOnlyOperation);
+            object.addOperation(outOnlyOperation);
 
             OutInAxisOperation outInOperation = new OutInAxisOperation(ServiceClient.ANON_OUT_IN_OP);
-            anonymousService.addOperation(outInOperation);
+            object.addOperation(outInOperation);
 
             // set a right default action *after* operations have been added to the service.
             outOnlyOperation.setSoapAction("");
@@ -434,9 +429,9 @@
             // and load the new config.
             init(); // create a new ServiceClient instance
             try {
-                 AxisUtils.configureService(_configContext, anonymousService, file.toURI().toURL());
+                 AxisUtils.configureService(_configContext, object, file.toURI().toURL());
                  // do not allow the service.xml file to change the service name
-                 anonymousService.setName(serviceName);
+                 object.setName(serviceName);
             } catch (Exception e) {
                 if (__log.isWarnEnabled()) __log.warn("Exception while configuring service: " + _serviceName, e);
                 throw new RuntimeException("Exception while configuring service: " + _serviceName, e);
@@ -444,23 +439,17 @@
         }
     }
 
-    private class OptionsObserver extends WatchDog.DefaultObserver {
-
-        Options options;
-
-        public boolean isInitialized() {
-            return options != null;
-        }
+    private class OptionsObserver extends WatchDog.DefaultObserver<Options> {
 
         public void init() {
-            options = new Options();
+            object = new Options();
             // set defaults values
-            options.setExceptionToBeThrownOnSOAPFault(false);
+            object.setExceptionToBeThrownOnSOAPFault(false);
 
             // this value does NOT override Properties.PROP_HTTP_CONNECTION_TIMEOUT
             // nor Properties.PROP_HTTP_SOCKET_TIMEOUT.
             // it will be applied only if the laters are not set.
-            options.setTimeOutInMilliSeconds(60000);
+            object.setTimeOutInMilliSeconds(60000);
         }
 
         public void onUpdate() {
@@ -468,7 +457,7 @@
 
             // note: don't make this map an instance attribute, so we always get the latest version
             final Map<String, String> properties = _pconf.getEndpointProperties(endpointReference);
-            Properties.Axis2.translate(properties, options);
+            Properties.Axis2.translate(properties, object);
         }
     }
 
@@ -490,7 +479,7 @@
         }
 
         public String toString() {
-            return "Properties for Endpoint: " + endpointReference;
+            return "Properties for Endpoint: " + _serviceName + "#" + _portName;
         }
     }
 

Modified: ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java?rev=753390&r1=753389&r2=753390&view=diff
==============================================================================
--- ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java (original)
+++ ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java Fri Mar 13 20:37:33 2009
@@ -93,11 +93,8 @@
     // cache the inMemory flag because XMLBeans objects are heavily synchronized (guarded by a coarse-grained lock)
     private volatile boolean _inMemory = false;
 
-    // provide the IL properties
-    private HierarchicalProperties ilProperties;
     // monitor the EPR property file and reload it if necessary
     private WatchDog<Map<File, Long>, PropertiesObserver> propertiesWatchDog;
-    private final ReadWriteLock ilPropertiesLock = new ReentrantReadWriteLock();
 
     private EndpointReferenceContext eprContext;
 
@@ -377,17 +374,7 @@
         // update properties if necessary
         // do it manually to save resources (instead of using a thread)
         propertiesWatchDog.check();
-        if (ilProperties == null) {
-            return Collections.EMPTY_MAP;
-        } else {
-            // take a lock so we can have a consistent snapshot of the properties
-            ilPropertiesLock.readLock().lock();
-            try {
-                return ilProperties.getProperties(service, port);
-            } finally {
-                ilPropertiesLock.readLock().unlock();
-            }
-        }
+        return propertiesWatchDog.getObserver().get().getProperties(service, port);
     }
 
     private class PropertiesMutable implements WatchDog.Mutable<Map<File, Long>> {
@@ -408,43 +395,25 @@
             }
         }
 
-        private class PropertiesObserver implements WatchDog.Observer {
+        private class PropertiesObserver extends WatchDog.DefaultObserver<HierarchicalProperties> {
 
             public void init() {
-                ilPropertiesLock.writeLock().lock();
-                try {
                     try {
                         // do not hold a reference on the file list, so that changes are handled
                         // and always create a new instance of the HierarchicalProperties
-                        ilProperties = new HierarchicalProperties(collectEndpointConfigFiles());
+                        object = new HierarchicalProperties(collectEndpointConfigFiles());
                     } catch (IOException e) {
                         throw new ContextException("Integration-Layer Properties cannot be loaded!", e);
                     }
-                } finally {
-                    ilPropertiesLock.writeLock().unlock();
-                }
-            }
-
-            public boolean isInitialized() {
-                return ilProperties != null;
             }
 
             public void onUpdate() {
-                ilPropertiesLock.writeLock().lock();
-                try {
                     init();
                     try {
-                        ilProperties.loadFiles();
+                        object.loadFiles();
                     } catch (IOException e) {
                         throw new ContextException("Integration-Layer Properties cannot be loaded!", e);
                     }
-                } finally {
-                    ilPropertiesLock.writeLock().unlock();
-                }
-            }
-
-            public void onDelete() {
-                init();
             }
         }
 

Modified: ode/trunk/utils/src/main/java/org/apache/ode/utils/WatchDog.java
URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/WatchDog.java?rev=753390&r1=753389&r2=753390&view=diff
==============================================================================
--- ode/trunk/utils/src/main/java/org/apache/ode/utils/WatchDog.java (original)
+++ ode/trunk/utils/src/main/java/org/apache/ode/utils/WatchDog.java Fri Mar 13 20:37:33 2009
@@ -27,6 +27,9 @@
 import java.util.HashMap;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
  * This class is based on {@link org.apache.log4j.helpers.FileWatchdog}.<p/>
@@ -112,36 +115,47 @@
     public final void check() {
         long now = System.currentTimeMillis();
         if (expire <= now) {
+            /* get a lock on the observer right now
+             It would be overkilled to lock before testing the dates.
+             By locking after the comparaison the worst scenario is that 2 threads get in the "if",
+             thread A gets the lock, thread B waits for it. Once the lock is released, thread B acquires it and do the checks on the mutable.
+             So this scenario is *harmless*.
+             */
+            observer.getLock().lock();
             expire = now + delay;
-            if (log.isDebugEnabled()) log.debug("["+mutable+"]"+ " check for changes");
-            if (mutable.exists()) {
-                existedBefore = true;
-                if (lastModif == null || mutable.hasChangedSince(lastModif)) {
-                    lastModif = mutable.lastModified();
-                    observer.onUpdate();
-                    if (log.isInfoEnabled()) log.info("["+mutable+"]"+" updated");
-                    warnedAlready = false;
-                }else{
-                    if (log.isDebugEnabled()) log.debug("["+mutable+"]"+" has not changed");
-                }
-            } else if (!observer.isInitialized()) {
-                // no resource and first time
-                observer.init();
-                if (log.isInfoEnabled()) log.info("["+mutable+"]"+ " initialized");
-            } else {
-                if (existedBefore) {
-                    existedBefore = false;
-                    lastModif = null;
-                    observer.onDelete();
-                    if (log.isInfoEnabled()) log.info("["+mutable+"]"+ " deleted");
-                }
-                if (!warnedAlready) {
-                    warnedAlready = true;
-                    if (log.isInfoEnabled()) log.info("["+mutable+"]"+" does not exist.");
+            try {
+                if (log.isDebugEnabled()) log.debug("[" + mutable + "]" + " check for changes");
+                if (mutable.exists()) {
+                    existedBefore = true;
+                    if (lastModif == null || mutable.hasChangedSince(lastModif)) {
+                        lastModif = mutable.lastModified();
+                        observer.onUpdate();
+                        if (log.isInfoEnabled()) log.info("[" + mutable + "]" + " updated");
+                        warnedAlready = false;
+                    } else {
+                        if (log.isDebugEnabled()) log.debug("[" + mutable + "]" + " has not changed");
+                    }
+                } else if (!observer.isInitialized()) {
+                    // no resource and first time
+                    observer.init();
+                    if (log.isInfoEnabled()) log.info("[" + mutable + "]" + " initialized");
+                } else {
+                    if (existedBefore) {
+                        existedBefore = false;
+                        lastModif = null;
+                        observer.onDelete();
+                        if (log.isInfoEnabled()) log.info("[" + mutable + "]" + " deleted");
+                    }
+                    if (!warnedAlready) {
+                        warnedAlready = true;
+                        if (log.isInfoEnabled()) log.info("[" + mutable + "]" + " does not exist.");
+                    }
                 }
+            } finally {
+                observer.getLock().unlock();
             }
-        }else{
-            if (log.isTraceEnabled()) log.trace("["+mutable+"]"+" wait period is not over");
+        } else {
+            if (log.isTraceEnabled()) log.trace("[" + mutable + "]" + " wait period is not over");
         }
     }
 
@@ -218,11 +232,10 @@
         }
     }
 
-    public interface Observer {
+    public interface Observer<A> {
 
         boolean isInitialized();
 
-
         /**
          * Called by {@link WatchDog#check()} if the underlying object is not {@link #isInitialized initialized} and the {@link WatchDog.Mutable#exists()}  resource does not exist}.
          * <br/> This method might called to reset the underlying object.
@@ -247,19 +260,26 @@
          */
         void onUpdate();
 
+        Lock getLock();
+
+        A get();
+
     }
 
     /**
      * A default implementation of #ChangeHandler. Delete and Update will both invoke the #init method which satifies most use cases.
      * So subclasses may simply override the #init method to fit their own needs.
      */
-    public static class DefaultObserver implements Observer {
+    public static class DefaultObserver<A> implements Observer<A> {
+
+        protected final ReadWriteLock lock = new ReentrantReadWriteLock();
+        protected A object;
 
         /**
-         * @return true
+         * @return true if the wrapped if not null
          */
         public boolean isInitialized() {
-            return true;
+            return object != null;
         }
 
         /**
@@ -282,5 +302,17 @@
             init();
         }
 
+        public Lock getLock() {
+            return lock.writeLock();
+        }
+
+        public A get() {
+            lock.readLock().lock();
+            try {
+                return object;
+            } finally {
+                lock.readLock().unlock();
+            }
+        }
     }
 }