/** * Constructs a task based on creation info (task type and task parameters as retrieved from the * vdsm). Use in order to construct tasks when service is initializing. * * @param coco Handle to command coordinator * @param creationInfo The Asyc Task Creation info */ public static SPMAsyncTask construct( CommandCoordinator coco, AsyncTaskCreationInfo creationInfo) { AsyncTask asyncTask = coco.getByVdsmTaskId(creationInfo.getVdsmTaskId()); if (asyncTask == null || asyncTask.getActionParameters() == null) { asyncTask = new AsyncTask( AsyncTaskResultEnum.success, AsyncTaskStatusEnum.running, Guid.Empty, creationInfo.getVdsmTaskId(), creationInfo.getStepId(), creationInfo.getStoragePoolID(), creationInfo.getTaskType(), getCommandEntity( coco, asyncTask == null ? Guid.newGuid() : asyncTask.getRootCommandId()), getCommandEntity( coco, asyncTask == null ? Guid.newGuid() : asyncTask.getCommandId())); creationInfo.setTaskType(AsyncTaskType.unknown); } AsyncTaskParameters asyncTaskParams = new AsyncTaskParameters(creationInfo, asyncTask); return construct(coco, creationInfo.getTaskType(), asyncTaskParams, true); }
/** * Retrieves from the specified storage pool the tasks that exist on it and adds them to the * manager. * * @param sp the storage pool to retrieve running tasks from */ public void addStoragePoolExistingTasks(StoragePool sp) { List<AsyncTaskCreationInfo> currPoolTasks = null; try { currPoolTasks = coco.getAllTasksInfo(sp.getId()); } catch (RuntimeException e) { log.error( "Getting existing tasks on Storage Pool '{}' failed: {}", sp.getName(), e.getMessage()); log.debug("Exception", e); } if (currPoolTasks != null && currPoolTasks.size() > 0) { synchronized (this) { final List<SPMTask> newlyAddedTasks = new ArrayList<>(); for (AsyncTaskCreationInfo creationInfo : currPoolTasks) { creationInfo.setStoragePoolID(sp.getId()); if (!_tasks.containsKey(creationInfo.getVdsmTaskId())) { try { SPMTask task; if (partiallyCompletedCommandTasks.containsKey(creationInfo.getVdsmTaskId())) { AsyncTask asyncTaskInDb = partiallyCompletedCommandTasks.get(creationInfo.getVdsmTaskId()); task = coco.construct(creationInfo, asyncTaskInDb); if (task.getEntitiesMap() == null) { task.setEntitiesMap(new HashMap<>()); } partiallyCompletedCommandTasks.remove(task.getVdsmTaskId()); // mark it as a task of a partially completed command // Will result in failure of the command task.setPartiallyCompletedCommandTask(true); } else { task = coco.construct(creationInfo); } addTaskToManager(task); newlyAddedTasks.add(task); } catch (Exception e) { log.error( "Failed to load task of type '{}' with id '{}': {}.", creationInfo.getTaskType(), creationInfo.getVdsmTaskId(), ExceptionUtils.getRootCauseMessage(e)); log.debug("Exception", e); } } } TransactionSupport.executeInNewTransaction( () -> { for (SPMTask task : newlyAddedTasks) { AsyncTaskUtils.addOrUpdateTaskInDB(task); } return null; }); for (SPMTask task : newlyAddedTasks) { startPollingTask(task.getVdsmTaskId()); } log.info( "Discovered {} tasks on Storage Pool '{}', {} added to manager.", currPoolTasks.size(), sp.getName(), newlyAddedTasks.size()); } } else { log.info("Discovered no tasks on Storage Pool '{}'", sp.getName()); } List<AsyncTask> tasksInDForStoragePool = tasksInDbAfterRestart.get(sp.getId()); if (tasksInDForStoragePool != null) { for (AsyncTask task : tasksInDForStoragePool) { if (!_tasks.containsKey(task.getVdsmTaskId())) { coco.removeByVdsmTaskId(task.getVdsmTaskId()); } } } // Either the tasks were only in DB - so they were removed from db, or they are polled - // in any case no need to hold them in the map that represents the tasksInDbAfterRestart tasksInDbAfterRestart.remove(sp.getId()); }