diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml index 5bf23666ca..60299a77a8 100644 --- a/config/alfresco/action-services-context.xml +++ b/config/alfresco/action-services-context.xml @@ -123,6 +123,9 @@ + + + diff --git a/config/alfresco/cache-context.xml b/config/alfresco/cache-context.xml index 84a316b756..5ef22757f4 100644 --- a/config/alfresco/cache-context.xml +++ b/config/alfresco/cache-context.xml @@ -1034,4 +1034,23 @@ - \ No newline at end of file + + + + + + + + + + + + + + org.alfresco.cache.executingActionsSharedCache + + + + + + diff --git a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java index 3f4d634116..5a84e391bb 100644 --- a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java +++ b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java @@ -18,8 +18,12 @@ */ package org.alfresco.repo.action; +import java.util.ArrayList; +import java.util.Collection; import java.util.Date; +import java.util.List; +import org.alfresco.repo.cache.EhCacheAdapter; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; @@ -28,6 +32,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionStatus; import org.alfresco.service.cmr.action.ActionTrackingService; +import org.alfresco.service.cmr.action.CancellableAction; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.transaction.TransactionService; import org.apache.commons.logging.Log; @@ -45,9 +50,19 @@ public class ActionTrackingServiceImpl implements ActionTrackingService */ private static Log logger = LogFactory.getLog(ActionTrackingServiceImpl.class); + // TODO - Fix types + private EhCacheAdapter executingActionsCache; + private TransactionService transactionService; private RuntimeActionService runtimeActionService; + /** + * Doesn't need to be cluster unique, is just used + * to try to reduce the chance of clashes in the + * quickest and easiest way. + */ + private short nextExecutionId = 1; + /** * Set the transaction service * @@ -67,8 +82,19 @@ public class ActionTrackingServiceImpl implements ActionTrackingService { this.runtimeActionService = runtimeActionService; } + + /** + * Sets the cache used to store details of + * currently executing actions, cluster wide. + * TODO Fix types + */ + public void setExecutingActionsCache(EhCacheAdapter executingActionsCache) + { + this.executingActionsCache = executingActionsCache; + } + public void recordActionPending(Action action) { ((ActionImpl)action).setExecutionStatus(ActionStatus.Pending); @@ -163,4 +189,91 @@ public class ActionTrackingServiceImpl implements ActionTrackingService ); } } + + public boolean isCancellationRequested(CancellableAction action) + { + // If the action isn't in the cache, but is of + // status executing, then put it back into the + // cache and warn + // (Probably means the cache is too small) + + // Retrieve from the cache, and see if cancellation + // has been requested + + // TODO + return false; + } + + public void requestActionCancellation(CancellableAction action) + { + // See if the action is in the cache + // If it isn't, nothing to do + // If it is, update the cancelled flag on it + // TODO + } + + public List getAllExecutingActions() { + Collection actions = executingActionsCache.getKeys(); + // TODO fix types + List details = new ArrayList(actions.size()); + for(String key : actions) { + //details.add( buildExecutionSummary(key) ); + } + return details; + } + + public List getExecutingActions(Action action) { + Collection actions = executingActionsCache.getKeys(); + // TODO fix types + List details = new ArrayList(); + String match = action.getActionDefinitionName() + "-" + action.getId(); + for(String key : actions) { + if(key.startsWith(match)) { + //details.add( buildExecutionSummary(key) ); + } + } + return details; + } + + public List getExecutingActions(String type) { + Collection actions = executingActionsCache.getKeys(); + // TODO fix types + List details = new ArrayList(); + for(String key : actions) { + if(key.startsWith(type)) { + //details.add( buildExecutionSummary(key) ); + } + } + return details; + } + + public void getExecutionDetails(Void executionSummary) { + // TODO Auto-generated method stub + + } + + public void requestActionCancellation(Void executionSummary) { + // TODO Auto-generated method stub + + } + + /** + * Generates the cache key for the specified action. + */ + protected String generateCacheKey(Action action) + { + // TODO + return null; + } + + /** + * Turns a cache key back into its constituent + * parts, for easier access. + * TODO Fix types + */ + protected void buildExecutionSummary(String key) + { + + } + } diff --git a/source/java/org/alfresco/service/cmr/action/ActionTrackingService.java b/source/java/org/alfresco/service/cmr/action/ActionTrackingService.java index 843e88bb20..8d2dfa8a1e 100644 --- a/source/java/org/alfresco/service/cmr/action/ActionTrackingService.java +++ b/source/java/org/alfresco/service/cmr/action/ActionTrackingService.java @@ -18,6 +18,8 @@ */ package org.alfresco.service.cmr.action; +import java.util.List; + import org.alfresco.service.PublicService; /** @@ -59,4 +61,73 @@ public interface ActionTrackingService * @param action the action that has failed */ void recordActionFailure(Action action, Throwable problem); + + /** + * Requests that the specified Action cancel itself + * and aborts execution, as soon as possible. + * Cancellable actions periodically check to see + * if a cancel has been requested, and will take + * note of the cancel request once seen. + * + * @param action The action to request the cancel of + */ + void requestActionCancellation(CancellableAction action); + + /** + * Requests that the specified Action cancel itself + * and aborts execution, as soon as possible. + * Cancellable actions periodically check to see + * if a cancel has been requested, and will take + * note of the cancel request once seen. + * If the specified action is not a cancellable + * action, nothing will happen. + * + * TODO Correct param type - is key based data only. + * @param action The action to request the cancel of + */ + void requestActionCancellation(Void executionSummary); + + /** + * Has cancellation been requested for the given + * action? + * This method is most commonly called by the + * action in question, to check to see if + * someone has called {@link #requestActionCancellation(CancellableAction)} + * for them. + * + * @param action The action to check about + * @return if cancellation has been requested or not + */ + boolean isCancellationRequested(CancellableAction action); + + /** + * Retrieves the execution details on the given + * executing action, such as when it started, + * and what machine it is executing on. + * TODO Correct param type - is key based data only. + * TODO Correct return type - is all cache data + */ + void getExecutionDetails(Void executionSummary); + + /** + * Retrieve summary details of all the actions + * currently executing. + * TODO Correct return type - is key based data only. + */ + List getAllExecutingActions(); + + /** + * Retrieve summary details of all the actions + * of the given type that are currently executing. + * TODO Correct return type - is key based data only. + */ + List getExecutingActions(String type);//or is it qname? + + /** + * Retrieve summary details of all instances of + * the specified action that are currently + * executing. + * TODO Correct return type - is key based data only. + */ + List getExecutingActions(Action action); }