Ravi Nori has uploaded a new change for review.

Change subject: engine : Command Executor should persist command before 
submitting to threadpool
......................................................................

engine : Command Executor should persist command before submitting to threadpool

Command Coordinator should persist command before
submitting command to thread pool for execution. On
server restarted the commands that have not started
execution are failed

Change-Id: I4d510836dc822a95198dc1db4a4f74206466f0c9
Bug-Url: https://bugzilla.redhat.com/1113256
Signed-off-by: Ravi Nori <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandExecutor.java
1 file changed, 79 insertions(+), 18 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/93/30693/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandExecutor.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandExecutor.java
index 80692d2..b6d2b4e 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandExecutor.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandExecutor.java
@@ -5,11 +5,15 @@
 import java.util.Map.Entry;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
+import org.ovirt.engine.core.bll.Backend;
 import org.ovirt.engine.core.bll.CommandBase;
 import org.ovirt.engine.core.bll.CommandsFactory;
 import org.ovirt.engine.core.bll.context.CommandContext;
@@ -21,6 +25,8 @@
 import org.ovirt.engine.core.common.businessentities.CommandEntity;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.errors.VdcBllErrors;
+import org.ovirt.engine.core.common.errors.VdcFault;
 import org.ovirt.engine.core.compat.CommandStatus;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.utils.log.Log;
@@ -66,9 +72,6 @@
                 coco.updateCallBackNotified(cmdId);
                 iterator.remove();
                 break;
-            case ACTIVE_SYNC:
-                
coco.retrieveCommand(cmdId).setCommandStatus(CommandStatus.FAILED_RESTARTED);
-                break;
             case ACTIVE:
             case ACTIVE_ASYNC:
                 callBack.doPolling(cmdId, coco.getChildCommandIds(cmdId));
@@ -82,8 +85,16 @@
     private void initCommandExecutor() {
         if (!cmdExecutorInitialized) {
             for (CommandEntity cmdEntity : 
coco.getCommandsWithCallBackEnabled()) {
-                if (!cmdEntity.isCallBackNotified()) {
-                    addToCallBackMap(cmdEntity);
+                switch(cmdEntity.getCommandStatus()) {
+                    case ACTIVE_SYNC:
+                    case NOT_STARTED:
+                        
coco.retrieveCommand(cmdEntity.getId()).setCommandStatus(CommandStatus.FAILED_RESTARTED);
+                        break;
+                    default:
+                        if (!cmdEntity.isCallBackNotified()) {
+                            addToCallBackMap(cmdEntity);
+                        }
+                        break;
                 }
             }
             cmdExecutorInitialized = true;
@@ -100,25 +111,34 @@
     }
 
     public Future<VdcReturnValueBase> executeAsyncCommand(final VdcActionType 
actionType,
-                                                          final 
VdcActionParametersBase parameters,
-                                                          final CommandContext 
cmdContext) {
+                                    final VdcActionParametersBase parameters,
+                                    final CommandContext cmdContext) {
         final CommandBase<?> command = 
CommandsFactory.createCommand(actionType, parameters, cmdContext);
-        coco.saveCommandContext(command.getCommandId(), cmdContext);
-        return executor.submit(new Callable<VdcReturnValueBase>() {
-
-            @Override
-            public VdcReturnValueBase call() throws Exception {
-                return executeCommand(command, cmdContext);
-            }
-        });
-    }
-
-    private VdcReturnValueBase executeCommand(final CommandBase<?> command, 
final CommandContext cmdContext) {
         command.persistCommand(command.getParameters().getParentCommand(), 
cmdContext, true);
         CommandCallBack callBack = command.getCallBack();
         if (callBack != null) {
             cmdCallBackMap.put(command.getCommandId(), callBack);
         }
+        Future<VdcReturnValueBase> retVal;
+        try {
+            retVal = executor.submit(new Callable<VdcReturnValueBase>() {
+
+                @Override
+                public VdcReturnValueBase call() throws Exception {
+                    return executeCommand(command, cmdContext);
+                }
+            });
+        } catch(RejectedExecutionException ex) {
+            command.setCommandStatus(CommandStatus.FAILED);
+            log.errorFormat("Failed to submit command to executor service, 
command {0} status has been set to FAILED",
+                    command.getCommandId().toString());
+            retVal = new RejectedExecutionFuture();
+        }
+        return retVal;
+    }
+
+    private VdcReturnValueBase executeCommand(final CommandBase<?> command, 
final CommandContext cmdContext) {
+        CommandCallBack callBack = command.getCallBack();
         VdcReturnValueBase result = 
BackendUtils.getBackendCommandObjectsHandler(log).runAction(command, null);
         updateCommand(command, result);
         if (callBack != null) {
@@ -140,4 +160,45 @@
         coco.persistCommand(cmdEntity);
     }
 
+    static class RejectedExecutionFuture implements Future<VdcReturnValueBase> 
{
+
+        VdcReturnValueBase retValue;
+
+        RejectedExecutionFuture() {
+            retValue = new VdcReturnValueBase();
+            retValue.setSucceeded(false);
+            VdcFault fault = new VdcFault();
+            fault.setError(VdcBllErrors.ResourceException);
+            fault.setMessage(Backend.getInstance()
+                    .getVdsErrorsTranslator()
+                    .TranslateErrorTextSingle(fault.getError().toString()));
+            retValue.setFault(fault);
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return false;
+        }
+
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public boolean isDone() {
+            return true;
+        }
+
+        @Override
+        public VdcReturnValueBase get() throws InterruptedException, 
ExecutionException {
+            return retValue;
+        }
+
+        @Override
+        public VdcReturnValueBase get(long timeout, TimeUnit unit) throws 
InterruptedException, ExecutionException, TimeoutException {
+            return retValue;
+        }
+    }
+
 }


-- 
To view, visit http://gerrit.ovirt.org/30693
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4d510836dc822a95198dc1db4a4f74206466f0c9
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5
Gerrit-Owner: Ravi Nori <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to