You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2006/12/14 12:24:57 UTC

svn commit: r487178 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: ./ config/ state/ version/

Author: dpfister
Date: Thu Dec 14 03:24:55 2006
New Revision: 487178

URL: http://svn.apache.org/viewvc?view=rev&rev=487178
Log:
JCR-676 Participation of a workspace in a cluster should be configurable
+ Allow derived implementations of SharedItemStateManager

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/config.dtd
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Thu Dec 14 03:24:55 2006
@@ -289,32 +289,11 @@
         virtNTMgr = new VirtualNodeTypeStateManager(getNodeTypeRegistry(),
                 delegatingDispatcher, NODETYPES_NODE_ID, SYSTEM_ROOT_NODE_ID);
 
-        // initialize default workspace
-        String wspName = repConfig.getDefaultWorkspaceName();
-        try {
-            initWorkspace((WorkspaceInfo) wspInfos.get(wspName));
-        } catch (RepositoryException e) {
-            // if default workspace failed to initialize, shutdown again
-            log.error("Failed to initialize workspace '" + wspName + "'", e);
-            log.error("Unable to start repository, forcing shutdown...");
-            shutdown();
-            throw e;
-        }
+        // initialize startup workspaces
+        initStartupWorkspaces();
 
         // initialize system search manager
-        getSystemSearchManager(wspName);
-
-        // amount of time in seconds before an idle workspace is automatically
-        // shut down
-        int maxIdleTime = repConfig.getWorkspaceMaxIdleTime();
-        if (maxIdleTime != 0) {
-            // start workspace janitor thread
-            Thread wspJanitor = new Thread(new WorkspaceJanitor(maxIdleTime * 1000));
-            wspJanitor.setName("WorkspaceJanitor");
-            wspJanitor.setPriority(Thread.MIN_PRIORITY);
-            wspJanitor.setDaemon(true);
-            wspJanitor.start();
-        }
+        getSystemSearchManager(repConfig.getDefaultWorkspaceName());
 
         // after the workspace is initialized we pass a system session to
         // the virtual node type manager
@@ -335,6 +314,18 @@
             }
         }
 
+        // amount of time in seconds before an idle workspace is automatically
+        // shut down
+        int maxIdleTime = repConfig.getWorkspaceMaxIdleTime();
+        if (maxIdleTime != 0) {
+            // start workspace janitor thread
+            Thread wspJanitor = new Thread(new WorkspaceJanitor(maxIdleTime * 1000));
+            wspJanitor.setName("WorkspaceJanitor");
+            wspJanitor.setPriority(Thread.MIN_PRIORITY);
+            wspJanitor.setDaemon(true);
+            wspJanitor.start();
+        }
+
         log.info("Repository started");
     }
 
@@ -372,6 +363,26 @@
     }
 
     /**
+     * Initialize startup workspaces. Base implementation will initialize the
+     * default workspace. Derived classes may initialize their own startup
+     * workspaces <b>after</b> having called the base implementation.
+     *
+     * @throws RepositoryException if an error occurs
+     */
+    protected void initStartupWorkspaces() throws RepositoryException {
+        String wspName = repConfig.getDefaultWorkspaceName();
+        try {
+            initWorkspace((WorkspaceInfo) wspInfos.get(wspName));
+        } catch (RepositoryException e) {
+            // if default workspace failed to initialize, shutdown again
+            log.error("Failed to initialize workspace '" + wspName + "'", e);
+            log.error("Unable to start repository, forcing shutdown...");
+            shutdown();
+            throw e;
+        }
+    }
+
+    /**
      * Lock the repository home.
      *
      * @throws RepositoryException if the repository lock can not be acquired
@@ -1168,6 +1179,29 @@
             throw new RepositoryException(msg, e);
         }
     }
+    
+    /**
+     * Creates a <code>SharedItemStateManager</code> or derivative.
+     *
+     * @param persistMgr     persistence manager
+     * @param rootNodeId     root node id
+     * @param ntReg          node type registry
+     * @param usesReferences <code>true</code> if the item state manager should use
+     *                       node references to verify integrity of its reference properties;
+     *                       <code>false</code> otherwise
+     * @param cacheFactory   cache factory
+     * @return item state manager
+     * @throws ItemStateException if an error occurs
+     */ 
+    protected SharedItemStateManager createItemStateManager(PersistenceManager persistMgr,
+                                                            NodeId rootNodeId,
+                                                            NodeTypeRegistry ntReg,
+                                                            boolean usesReferences,
+                                                            ItemStateCacheFactory cacheFactory)
+            throws ItemStateException {
+
+        return new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true, cacheFactory);
+    }
 
     //-----------------------------------------------------------< Repository >
     /**
@@ -1630,7 +1664,7 @@
                 // 'chicken & egg' bootstrap problems
                 if (lockMgr == null) {
                     lockMgr = new LockManagerImpl(getSystemSession(), fs);
-                    if (clusterNode != null) {
+                    if (clusterNode != null && config.isClustered()) {
                         lockChannel = clusterNode.createLockChannel(getName());
                         lockMgr.setEventChannel(lockChannel);
                     }
@@ -1725,8 +1759,7 @@
 
                 // create item state manager
                 try {
-                    itemStateMgr =
-                            new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true, cacheFactory);
+                    itemStateMgr = createItemStateManager(persistMgr, rootNodeId, ntReg, true, cacheFactory);
                     try {
                         itemStateMgr.addVirtualItemStateProvider(
                                 vMgr.getVirtualItemStateProvider());
@@ -1735,7 +1768,7 @@
                     } catch (Exception e) {
                         log.error("Unable to add vmgr: " + e.toString(), e);
                     }
-                    if (clusterNode != null) {
+                    if (clusterNode != null && config.isClustered()) {
                         updateChannel = clusterNode.createUpdateChannel(getName());
                         itemStateMgr.setEventChannel(updateChannel);
                         updateChannel.setListener(this);

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java Thu Dec 14 03:24:55 2006
@@ -112,6 +112,9 @@
     public static final String DEFAULT_QUERY_HANDLER =
         "org.apache.jackrabbit.core.query.lucene.SearchIndex";
 
+    /** Name of the clustered configuration attribute. */
+    public static final String CLUSTERED_ATTRIBUTE = "clustered";
+
     /**
      * Creates a new configuration parser with the given parser variables.
      *
@@ -330,6 +333,10 @@
         String name =
             getAttribute(root, NAME_ATTRIBUTE, new File(home).getName());
 
+        // Clustered attribute
+        boolean clustered = Boolean.valueOf(
+                getAttribute(root, CLUSTERED_ATTRIBUTE, "true")).booleanValue();
+
         // Create a temporary parser that contains the ${wsp.name} variable
         Properties tmpVariables = (Properties) getVariables().clone();
         tmpVariables.put(WORKSPACE_NAME_VARIABLE, name);
@@ -345,7 +352,7 @@
         // Search implementation (optional)
         SearchConfig sc = tmpParser.parseSearchConfig(root);
 
-        return new WorkspaceConfig(home, name, fsc, pmc, sc);
+        return new WorkspaceConfig(home, name, clustered, fsc, pmc, sc);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java Thu Dec 14 03:24:55 2006
@@ -38,6 +38,11 @@
     private final String name;
 
     /**
+     * Flag indicating whether this workspace participates in a cluster.
+     */
+    private final boolean clustered;
+
+    /**
      * Workspace file system configuration.
      */
     private FileSystemConfig fsc;
@@ -61,10 +66,12 @@
      * @param pmc persistence manager configuration
      * @param sc search index configuration
      */
-    public WorkspaceConfig(String home, String name, FileSystemConfig fsc,
-            PersistenceManagerConfig pmc, SearchConfig sc) {
+    public WorkspaceConfig(String home, String name, boolean clustered,
+                           FileSystemConfig fsc, PersistenceManagerConfig pmc,
+                           SearchConfig sc) {
         this.home = home;
         this.name = name;
+        this.clustered = clustered;
         this.fsc = fsc;
         this.pmc = pmc;
         this.sc = sc;
@@ -86,6 +93,16 @@
      */
     public String getName() {
         return name;
+    }
+
+    /**
+     * Returns a flag indicating whether this workspace participates in a cluster.
+     *
+     * @return <code>true</code> if this workspace participates in a cluster;
+     *         <code>false</code> otherwise
+     */
+    public boolean isClustered() {
+        return clustered;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/config.dtd
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/config.dtd?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/config.dtd (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/config.dtd Thu Dec 14 03:24:55 2006
@@ -125,11 +125,15 @@
 <!--
     the Workspace element serves as a workspace configuration template;
     it is used to create the initial workspace if there's no workspace yet
-    and for creating additional workspaces through the api
+    and for creating additional workspaces through the api; the clustered
+    attribute indicates whether the workspace should participate in an
+    optionally configured cluster
 -->
 <!ELEMENT Workspace (FileSystem,PersistenceManager,SearchIndex?)>
 <!ATTLIST Workspace
-  name CDATA #REQUIRED>
+  name CDATA #REQUIRED
+  clustered (true|false) "true"
+>
 
 <!--
     the PersistenceManager element configures the persistence manager

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Thu Dec 14 03:24:55 2006
@@ -817,48 +817,11 @@
     public void externalUpdate(ChangeLog external, EventStateCollection events) {
         boolean holdingWriteLock = false;
 
-        ChangeLog shared = new ChangeLog();
-
         try {
-            // Build a copy of the external change log, consisting of shared
-            // states we have in our cache. Inform listeners about this
-            // change.
             acquireWriteLock();
             holdingWriteLock = true;
 
-            Iterator modifiedStates = external.modifiedStates();
-            while (modifiedStates.hasNext()) {
-                ItemState state = (ItemState) modifiedStates.next();
-                state = cache.retrieve(state.getId());
-                if (state != null) {
-                    try {
-                        ItemState currentState = loadItemState(state.getId());
-                        state.copy(currentState);
-                        state.setModCount(currentState.getModCount());
-                        shared.modified(state);
-                    } catch (NoSuchItemStateException e) {
-                        // This is likely to happen because a subsequent delete
-                        // of this very state has not yet been transmitted.
-                        String msg = "Unable to retrieve state: " + state.getId() + ", ignored.";
-                        log.info(msg);
-                        state.discard();
-                    } catch (ItemStateException e) {
-                        String msg = "Unable to retrieve state: " + state.getId();
-                        log.warn(msg);
-                        state.discard();
-                    }
-                }
-            }
-            Iterator deletedStates = external.deletedStates();
-            while (deletedStates.hasNext()) {
-                ItemState state = (ItemState) deletedStates.next();
-                state = cache.retrieve(state.getId());
-                if (state != null) {
-                    shared.deleted(state);
-                }
-            }
-            shared.persisted();
-
+            doExternalUpdate(external);
         } catch (ItemStateException e) {
             String msg = "Unable to acquire write lock.";
             log.error(msg);
@@ -882,6 +845,52 @@
             }
         }
 
+    }
+
+    /**
+     * Perform the external update. While executing this method, the <code>writeLock</code>
+     * on this manager is held.
+     *
+     * @param external external change containing only node and property ids.
+     */
+    protected void doExternalUpdate(ChangeLog external) {
+        ChangeLog shared = new ChangeLog();
+
+        // Build a copy of the external change log, consisting of shared
+        // states we have in our cache. Inform listeners about this
+        // change.
+        Iterator modifiedStates = external.modifiedStates();
+        while (modifiedStates.hasNext()) {
+            ItemState state = (ItemState) modifiedStates.next();
+            state = cache.retrieve(state.getId());
+            if (state != null) {
+                try {
+                    ItemState currentState = loadItemState(state.getId());
+                    state.copy(currentState);
+                    state.setModCount(currentState.getModCount());
+                    shared.modified(state);
+                } catch (NoSuchItemStateException e) {
+                    // This is likely to happen because a subsequent delete
+                    // of this very state has not yet been transmitted.
+                    String msg = "Unable to retrieve state: " + state.getId() + ", ignored.";
+                    log.info(msg);
+                    state.discard();
+                } catch (ItemStateException e) {
+                    String msg = "Unable to retrieve state: " + state.getId();
+                    log.warn(msg);
+                    state.discard();
+                }
+            }
+        }
+        Iterator deletedStates = external.deletedStates();
+        while (deletedStates.hasNext()) {
+            ItemState state = (ItemState) deletedStates.next();
+            state = cache.retrieve(state.getId());
+            if (state != null) {
+                shared.deleted(state);
+            }
+        }
+        shared.persisted();
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java?view=diff&rev=487178&r1=487177&r2=487178
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java Thu Dec 14 03:24:55 2006
@@ -157,8 +157,7 @@
                 cl.added(pt);
                 pMgr.store(cl);
             }
-            sharedStateMgr =
-                    new VersionItemStateManager(pMgr, rootId, ntReg, cacheFactory);
+            sharedStateMgr = createSharedStateManager(pMgr, rootId, ntReg, cacheFactory);
 
             stateMgr = new LocalItemStateManager(sharedStateMgr, escFactory, cacheFactory);
             stateMgr.addListener(this);
@@ -463,6 +462,25 @@
      */
     SharedItemStateManager getSharedStateMgr() {
         return sharedStateMgr;
+    }
+
+    /**
+     * Creates a <code>SharedItemStateManager</code> or derivative.
+     *
+     * @param pMgr          persistence manager
+     * @param rootId        root node id
+     * @param ntReg         node type registry
+     * @param cacheFactory  cache factory
+     * @return item state manager
+     * @throws ItemStateException if an error occurs
+     */
+    protected SharedItemStateManager createSharedStateManager(PersistenceManager pMgr,
+                                                              NodeId rootId,
+                                                              NodeTypeRegistry ntReg,
+                                                              ItemStateCacheFactory cacheFactory)
+            throws ItemStateException {
+
+        return new VersionItemStateManager(pMgr, rootId, ntReg, cacheFactory);
     }
 
     /**