/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hasor.data.ql.runtime.task;
import net.hasor.core.future.BasicFuture;
import net.hasor.data.ql.runtime.QueryContext;
import net.hasor.data.ql.runtime.QueryTask;
import net.hasor.data.ql.runtime.TaskStatus;
import net.hasor.data.ql.runtime.TaskType;
import java.util.*;
import java.util.concurrent.ExecutionException;
/**
* @author 赵永春(zyc@hasor.net)
* @version : 2017-03-23
*/
public abstract class AbstractTask extends Observable implements QueryTask {
// - 核心字段
private String nameOfParent = null; // 在父节点中的名字
private AbstractTask parentTask = null; // 解析结构父节点
protected Map<String, AbstractTask> fieldTaskMap = null; // 解析结构子节点
protected List<AbstractTask> depTaskList = null; // 依赖的任务
private AbstractTask dataSource = null; // 数据源
// - 运行字段
private TaskStatus taskStatus = null;
private TaskType taskType = null; // 任务类型:D,数据源、F,字段
private BasicFuture<Object> result = null;
//
//
public AbstractTask(String nameOfParent, AbstractTask parentTask, AbstractTask dataSource) {
//
this.nameOfParent = nameOfParent;
this.parentTask = parentTask;
this.fieldTaskMap = new HashMap<String, AbstractTask>();
this.depTaskList = new ArrayList<AbstractTask>();
this.dataSource = dataSource;
this.addDepTask(dataSource);
//
this.taskStatus = TaskStatus.Prepare;
this.taskType = initTaskType();// 默认为 dataSource
this.result = new BasicFuture<Object>();
}
protected TaskType initTaskType() {
return TaskType.D;
}
//
//
/** 添加依赖的子任务 */
public void addDepTask(AbstractTask depTask) {
if (depTask == null) {
return;
}
if (this.depTaskList.contains(depTask)) {
return;
}
this.depTaskList.add(depTask);
depTask.addObserver(new Observer() {
public void update(Observable o, Object arg) {
// .子任务执行失败,整体失败
if (TaskStatus.Failed.equals(arg)) {
try {
((AbstractTask) o).getValue();
} catch (ExecutionException e) {
updateStatus(TaskStatus.Failed, e.getCause());
} catch (Throwable e) {
updateStatus(TaskStatus.Failed, e);
} finally {
return;
}
}
// .尝试跳入 Waiting 阶段
if (TaskStatus.Complete.equals(arg)) {
for (AbstractTask task : depTaskList) {
if (!task.isFinish()) {
return;
}
}
updateStatus(TaskStatus.Waiting, null);//所有子任务Finish,那么进入 Waiting
}
}
});
this.taskStatus = TaskStatus.Prepare;
}
/** 添加字段 */
protected void addFieldTask(String nameOfParent, AbstractTask fieldTask) {
if (fieldTask == null) {
return;
}
if (this.fieldTaskMap.containsKey(nameOfParent)) {
return;
}
/* 当一个 Task 成为 Field 之后。如果它不具备 DataSource,那么它的 TaskType 被设定为 F */
this.fieldTaskMap.put(nameOfParent, fieldTask);
if (fieldTask instanceof ValueTask || fieldTask instanceof CallerTask) {
fieldTask.taskType = TaskType.D;
} else {
fieldTask.taskType = (fieldTask.dataSource == null ? TaskType.F : TaskType.D);
}
//
this.addDepTask(fieldTask);
}
/** 获取字段 */
public AbstractTask findFieldTask(String nameOfParent) {
return this.fieldTaskMap.get(nameOfParent);
}
/** 获取父节点 */
public AbstractTask getParent() {
return this.parentTask;
}
/** 获取节点的数据源 */
public AbstractTask getDataSource() {
return this.dataSource;
}
/** 获取节点的数据类型 */
public TaskType getTaskType() {
return this.taskType;
}
/** 节点在父关系中的名称 */
public String getNameOfParent() {
return this.nameOfParent;
}
/** 判断当前节点是否为根节点 */
public boolean isRoot() {
return this.parentTask == null;
}
/** 节点状态 */
public TaskStatus getTaskStatus() {
return this.taskStatus;
}
/** 获取节点运行结果 */
public final Object getValue() throws ExecutionException, InterruptedException {
if (TaskType.F.equals(this.taskType)) {
return null;
}
if (this.result.isDone() && TaskType.D.equals(this.taskType)) {
return this.result.get();
}
if (this.result.isDone()) {
return this.result.get();
}
throw new IllegalStateException("result is not ready. -> cur status is " + this.taskStatus.name());
}
/** 是否等待调度:status = Waiting */
public boolean isWaiting() {
return TaskStatus.Waiting.equals(this.taskStatus);
}
/** 节点是否执行完毕:status = Complete | Failed */
public boolean isFinish() {
return TaskStatus.Complete.equals(this.taskStatus) || TaskStatus.Failed.equals(this.taskStatus);
}
//
//
public void run(QueryContext taskContext, Object inData) {
//
// - F 节点只更新状态。
if (TaskType.F.equals(this.getTaskType())) {
this.updateStatus(TaskStatus.Complete, null);
return;
}
// - 只处理 Waiting 状态的节点
if (!TaskStatus.Waiting.equals(this.getTaskStatus())) {
return;
}
synchronized (this) {
try {
if (this.dataSource != null) {
inData = this.dataSource.getValue();
}
//
this.updateStatus(TaskStatus.Running, null);
Object taskResult = this.doTask(taskContext, inData);
this.result.completed(taskResult);
this.updateStatus(TaskStatus.Complete, null);
} catch (Throwable e) {
this.updateStatus(TaskStatus.Failed, e);
}
}
return;
}
protected void updateStatus(TaskStatus taskStatus, Throwable e) {
if (taskStatus == TaskStatus.Failed) {
this.result.failed(e);
}
try {
if (taskStatus == TaskStatus.Waiting) {
for (AbstractTask task : this.depTaskList) {
if (!task.isFinish()) {
return;/* 所有子任务都完成,才进入 Waiting */
}
}
}
this.taskStatus = taskStatus;
if (taskStatus == TaskStatus.Prepare) {
for (AbstractTask task : this.depTaskList) {
if (!task.isFinish()) {
return;/* 所有子任务都完成,才进入 Waiting */
}
}
this.updateStatus(TaskStatus.Waiting, null);
}
} finally {
this.setChanged();
this.notifyObservers(this.taskStatus);
}
}
/** 执行任务*/
public abstract Object doTask(QueryContext taskContext, Object inData) throws Throwable;
//
//
public AbstractTask fixRouteDep() {
for (AbstractTask task : this.depTaskList) {
task.fixRouteDep();
}
if (this.depTaskList.isEmpty()) {
if (TaskType.F == this.taskType) {
this.updateStatus(TaskStatus.Complete, null);
} else {
this.updateStatus(TaskStatus.Waiting, null);
}
}
return this;
}
/** 获取所有待执行的任务列表。 */
public List<AbstractTask> getAllTask() {
return addToAllTask(this, new ArrayList<AbstractTask>());
}
private static List<AbstractTask> addToAllTask(AbstractTask task, List<AbstractTask> allTask) {
if (!allTask.contains(task)) {
allTask.add(task);
}
for (AbstractTask subTask : task.depTaskList) {
if (!allTask.contains(subTask)) {
allTask.add(subTask);
}
addToAllTask(subTask, allTask);
}
return allTask;
}
}