You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by fr...@apache.org on 2017/01/26 13:34:11 UTC

svn commit: r1780389 - /jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java

Author: frm
Date: Thu Jan 26 13:34:11 2017
New Revision: 1780389

URL: http://svn.apache.org/viewvc?rev=1780389&view=rev
Log:
OAK-5522 - Make deactivation code in StandbyStoreService resilient to exceptions

Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java?rev=1780389&r1=1780388&r2=1780389&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java Thu Jan 26 13:34:11 2017
@@ -14,15 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.jackrabbit.oak.segment.standby.store;
 
 import static java.lang.String.valueOf;
 import static org.apache.felix.scr.annotations.ReferencePolicy.STATIC;
 import static org.apache.felix.scr.annotations.ReferencePolicyOption.GREEDY;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.Dictionary;
 import java.util.Hashtable;
 
+import com.google.common.io.Closer;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.ConfigurationPolicy;
@@ -41,113 +45,108 @@ import org.osgi.service.component.Compon
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Property(name = "org.apache.sling.installer.configuration.persist", label="Persist configuration", description = "Must be always disabled to avoid storing the configuration in the repository", boolValue = false)
+@Property(name = "org.apache.sling.installer.configuration.persist", label = "Persist configuration", description = "Must be always disabled to avoid storing the configuration in the repository", boolValue = false)
 @Component(metatype = true, policy = ConfigurationPolicy.REQUIRE)
 public class StandbyStoreService {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private static final String MODE_PRIMARY = "primary";
+
     private static final String MODE_STANDBY = "standby";
 
     public static final String MODE_DEFAULT = MODE_PRIMARY;
+
     @Property(options = {
             @PropertyOption(name = MODE_PRIMARY, value = MODE_PRIMARY),
-            @PropertyOption(name = MODE_STANDBY, value = MODE_STANDBY) },
+            @PropertyOption(name = MODE_STANDBY, value = MODE_STANDBY)},
             value = MODE_DEFAULT)
     public static final String MODE = "mode";
 
     public static final int PORT_DEFAULT = 8023;
+
     @Property(intValue = PORT_DEFAULT)
     public static final String PORT = "port";
 
     public static final String PRIMARY_HOST_DEFAULT = "127.0.0.1";
+
     @Property(value = PRIMARY_HOST_DEFAULT)
     public static final String PRIMARY_HOST = "primary.host";
 
     public static final int INTERVAL_DEFAULT = 5;
+
     @Property(intValue = INTERVAL_DEFAULT)
     public static final String INTERVAL = "interval";
 
     public static final String[] ALLOWED_CLIENT_IP_RANGES_DEFAULT = new String[] {};
+
     @Property(cardinality = Integer.MAX_VALUE)
     public static final String ALLOWED_CLIENT_IP_RANGES = "primary.allowed-client-ip-ranges";
 
     public static final boolean SECURE_DEFAULT = false;
+
     @Property(boolValue = SECURE_DEFAULT)
     public static final String SECURE = "secure";
 
     public static final int READ_TIMEOUT_DEFAULT = 60000;
+
     @Property(intValue = READ_TIMEOUT_DEFAULT)
     public static final String READ_TIMEOUT = "standby.readtimeout";
 
     public static final boolean AUTO_CLEAN_DEFAULT = false;
+
     @Property(boolValue = AUTO_CLEAN_DEFAULT)
     public static final String AUTO_CLEAN = "standby.autoclean";
 
     @Reference(policy = STATIC, policyOption = GREEDY)
     private SegmentStoreProvider storeProvider = null;
 
-    private FileStore fileStore;
-
-    private StandbyServerSync serverSync = null;
-
-    private StandbyClientSync clientSync = null;
-
-    private ServiceRegistration syncReg = null;
+    private Closer closer = Closer.create();
 
     @Activate
     private void activate(ComponentContext context) {
-        if (storeProvider == null) {
-            throw new IllegalArgumentException("Missing SegmentStoreProvider service");
-        }
-
         SegmentStore segmentStore = storeProvider.getSegmentStore();
 
         if (!(segmentStore instanceof FileStore)) {
             throw new IllegalArgumentException("Unexpected SegmentStore implementation");
         }
 
-        fileStore = (FileStore) segmentStore;
+        FileStore fileStore = (FileStore) segmentStore;
 
         String mode = valueOf(context.getProperties().get(MODE));
+
         if (MODE_PRIMARY.equals(mode)) {
-            bootstrapMaster(context);
-        } else if (MODE_STANDBY.equals(mode)) {
-            bootstrapSlave(context);
-        } else {
-            throw new IllegalArgumentException(
-                    "Unexpected 'mode' param, expecting 'primary' or 'standby' got "
-                            + mode);
+            bootstrapMaster(context, fileStore);
+            return;
         }
-    }
 
-    @Deactivate
-    public synchronized void deactivate() {
-        if (serverSync != null) {
-            serverSync.close();
+        if (MODE_STANDBY.equals(mode)) {
+            bootstrapSlave(context, fileStore);
+            return;
         }
 
-        if (clientSync != null) {
-            clientSync.close();
-        }
+        throw new IllegalArgumentException(String.format("Unexpected mode property, got '%s'", mode));
+    }
 
-        if (syncReg != null) {
-            syncReg.unregister();
-        }
+    @Deactivate
+    public void deactivate() throws Exception {
+        closer.close();
     }
 
-    private void bootstrapMaster(ComponentContext context) {
+    private void bootstrapMaster(ComponentContext context, FileStore fileStore) {
         Dictionary<?, ?> props = context.getProperties();
         int port = PropertiesUtil.toInteger(props.get(PORT), PORT_DEFAULT);
         String[] ranges = PropertiesUtil.toStringArray(props.get(ALLOWED_CLIENT_IP_RANGES), ALLOWED_CLIENT_IP_RANGES_DEFAULT);
         boolean secure = PropertiesUtil.toBoolean(props.get(SECURE), SECURE_DEFAULT);
-        serverSync = new StandbyServerSync(port, fileStore, ranges, secure);
-        serverSync.start();
-        log.info("started primary on port {} with allowed ip ranges {}.", port, ranges);
+
+        StandbyServerSync standbyServerSync = new StandbyServerSync(port, fileStore, ranges, secure);
+        closer.register(standbyServerSync);
+        standbyServerSync.start();
+
+        log.info("Started primary on port {} with allowed IP ranges {}", port, ranges);
     }
 
-    private void bootstrapSlave(ComponentContext context) {
+    private void bootstrapSlave(ComponentContext context, FileStore fileStore) {
         Dictionary<?, ?> props = context.getProperties();
         int port = PropertiesUtil.toInteger(props.get(PORT), PORT_DEFAULT);
         long interval = PropertiesUtil.toInteger(props.get(INTERVAL), INTERVAL_DEFAULT);
@@ -156,15 +155,27 @@ public class StandbyStoreService {
         int readTimeout = PropertiesUtil.toInteger(props.get(READ_TIMEOUT), READ_TIMEOUT_DEFAULT);
         boolean clean = PropertiesUtil.toBoolean(props.get(AUTO_CLEAN), AUTO_CLEAN_DEFAULT);
 
-        clientSync = new StandbyClientSync(host, port, fileStore, secure, readTimeout, clean);
+        StandbyClientSync standbyClientSync = new StandbyClientSync(host, port, fileStore, secure, readTimeout, clean);
+        closer.register(standbyClientSync);
+
         Dictionary<Object, Object> dictionary = new Hashtable<Object, Object>();
         dictionary.put("scheduler.period", interval);
         dictionary.put("scheduler.concurrent", false);
-        // dictionary.put("scheduler.runOn", "SINGLE");
+        ServiceRegistration registration = context.getBundleContext().registerService(Runnable.class.getName(), standbyClientSync, dictionary);
+        closer.register(asCloseable(registration));
 
-        syncReg = context.getBundleContext().registerService(
-                Runnable.class.getName(), clientSync, dictionary);
-        log.info("started standby sync with {}:{} at {} sec.", host,
-                port, interval);
+        log.info("Started standby on port {} with {}s sync frequency", port, interval);
     }
+
+    private static Closeable asCloseable(final ServiceRegistration r) {
+        return new Closeable() {
+
+            @Override
+            public void close() throws IOException {
+                r.unregister();
+            }
+
+        };
+    }
+
 }