diff --git a/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java b/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java index 3c243c34d5..1ee9c0f55a 100644 --- a/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java +++ b/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java @@ -1082,17 +1082,31 @@ public class TaggingServiceImplTest extends TestCase assertTrue("Not found in " + pendingScopes, pendingScopes.contains(this.subFolder)); + // Have the Quartz bean fire now + // It won't be able to do anything, as the locks are taken + UpdateTagScopesQuartzJob job = new UpdateTagScopesQuartzJob(); + job.execute(actionService, updateTagsAction); + tx = waitForActionExecution(tx); + + // Check that things are still pending despite the quartz run + assertEquals(2, updateTagsAction.searchForTagScopesPendingUpdates().size()); + pendingScopes = updateTagsAction.searchForTagScopesPendingUpdates(); + assertTrue("Not found in " + pendingScopes, pendingScopes.contains(this.folder)); + assertTrue("Not found in " + pendingScopes, pendingScopes.contains(this.subFolder)); + + // Give back our locks, so we can proceed updateTagsAction.unlockTagScope(this.folder, lockF); updateTagsAction.unlockTagScope(this.subFolder, lockSF); - // Fire off the quartz bean - UpdateTagScopesQuartzJob job = new UpdateTagScopesQuartzJob(); + // Fire off the quartz bean, this time it can really work + job = new UpdateTagScopesQuartzJob(); job.execute(actionService, updateTagsAction); + tx = waitForActionExecution(tx); - // Now check again + // Now check again - nothing should be pending assertEquals(0, updateTagsAction.searchForTagScopesPendingUpdates().size()); ts1 = this.taggingService.findTagScope(this.folder); diff --git a/source/java/org/alfresco/repo/tagging/UpdateTagScopesQuartzJob.java b/source/java/org/alfresco/repo/tagging/UpdateTagScopesQuartzJob.java index 22239b1b47..20836cd912 100644 --- a/source/java/org/alfresco/repo/tagging/UpdateTagScopesQuartzJob.java +++ b/source/java/org/alfresco/repo/tagging/UpdateTagScopesQuartzJob.java @@ -19,6 +19,8 @@ package org.alfresco.repo.tagging; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.security.authentication.AuthenticationUtil; @@ -77,9 +79,11 @@ public class UpdateTagScopesQuartzJob implements Job { { // Process final ArrayList tagNodes = new ArrayList(); + final HashSet handledTagNodes = new HashSet(); + while(true) { - // Fetch the list of changes + // Fetch a batch of the pending changes AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { public Void doWork() throws Exception @@ -93,12 +97,27 @@ public class UpdateTagScopesQuartzJob implements Job { }, AuthenticationUtil.getSystemUserName() ); - // Log what we found + // If we're on our 2nd loop round for any of them, then skip them from now on + // (This can happen if another thread is already processing one of them) + Iterator it = tagNodes.iterator(); + while(it.hasNext()) + { + NodeRef nodeRef = it.next(); + if(handledTagNodes.contains(nodeRef)) + { + it.remove(); + if(logger.isDebugEnabled()) + logger.debug("Tag scope " + nodeRef + " must be being processed by another Thread, not updating it"); + } + } + + // Log what we found to process if(logger.isDebugEnabled()) { logger.debug("Checked for tag scopes with pending tag updates, found " + tagNodes); } + // If we're out of tag scopes, stop! if(tagNodes.size() == 0) break; @@ -107,6 +126,9 @@ public class UpdateTagScopesQuartzJob implements Job { Action action = actionService.createAction(UpdateTagScopesActionExecuter.NAME); action.setParameterValue(UpdateTagScopesActionExecuter.PARAM_TAG_SCOPES, (Serializable)tagNodes); actionService.executeAction(action, null, false, false); + + // Record the scopes we've just done + handledTagNodes.addAll(tagNodes); } } }