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
