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);
}
/**