Browse Source
* 1, master persistent task 2. extract master and worker communication model * 1, master persistent task 2. extract master and worker communication model * 1, master persistent task 2. extract master and worker communication model * add license * modify javadoc error * TaskExecutionContext create modify * buildAckCommand taskInstanceId not set modify * java doc error modify * add comment * ExecutorManager interface add generic type * add TaskInstanceCacheManager receive Worker report result * TaskInstance setExecutePath * add TaskInstanceCacheManager to receive Worker Task result report * TaskInstanceCacheManager add remove method * add license * add dispatcht task method * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * AbstractCommandExecutor remove db access * taskInstanceCache is null ,need load from db * taskInstanceCache is null ,need load from db * taskInstanceCache is null ,need load from db * 1,worker TaskPros use TaskExecutionContext replase 2,Master kill Task , KillTaskProcessor modifypull/2/head
qiaozhanwei
5 years ago
committed by
GitHub
44 changed files with 886 additions and 1413 deletions
@ -1 +1 @@ |
|||||||
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
import java.util.Date;
/**
* execute task request command
*/
public class ExecuteTaskAckCommand implements Serializable {
private int taskInstanceId;
private Date startTime;
private String host;
private int status;
private String logPath;
private String executePath;
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public String getLogPath() {
return logPath;
}
public void setLogPath(String logPath) {
this.logPath = logPath;
}
public String getExecutePath() {
return executePath;
}
public void setExecutePath(String executePath) {
this.executePath = executePath;
}
/**
* package request command
*
* @return command
*/
public Command convert2Command(){
Command command = new Command();
command.setType(CommandType.EXECUTE_TASK_ACK);
byte[] body = FastJsonSerializer.serialize(this);
command.setBody(body);
return command;
}
@Override
public String toString() {
return "ExecuteTaskAckCommand{" +
"taskInstanceId=" + taskInstanceId +
", startTime=" + startTime +
", host='" + host + '\'' +
", status=" + status +
", logPath='" + logPath + '\'' +
", executePath='" + executePath + '\'' +
'}';
}
} |
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
import java.util.Date;
/**
* execute task request command
*/
public class ExecuteTaskAckCommand implements Serializable {
/**
* taskInstanceId
*/
kd">private int taskInstanceId;
kd">private int taskInstanceId;
kd">private int taskInstanceId;
kd">private int taskInstanceId;
private Date startTime;
kd">private int taskInstanceId;
private String host;
*/
kd">private int taskInstanceId;
private int status;
kd">private int taskInstanceId;
/**
kd">private int taskInstanceId;
private String logPath;
*/
kd">private int taskInstanceId;
/**
* status
*/
private int status;
/**
* logPath
*/
private String logPath;
/**
* executePath
*/
private String executePath;
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public String getLogPath() {
return logPath;
}
public void setLogPath(String logPath) {
this.logPath = logPath;
}
public String getExecutePath() {
return executePath;
}
public void setExecutePath(String executePath) {
this.executePath = executePath;
}
/**
* package request command
*
* @return command
*/
public Command convert2Command(){
Command command = new Command();
command.setType(CommandType.EXECUTE_TASK_ACK);
byte[] body = FastJsonSerializer.serialize(this);
command.setBody(body);
return command;
}
@Override
public String toString() {
return "ExecuteTaskAckCommand{" +
"taskInstanceId=" + taskInstanceId +
", startTime=" + startTime +
", host='" + host + '\'' +
", status=" + status +
", logPath='" + logPath + '\'' +
", executePath='" + executePath + '\'' +
'}';
}
} |
@ -1 +1 @@ |
|||||||
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
import java.util.Date;
/**
* execute task response command
*/
public class ExecuteTaskResponseCommand implements Serializable {
public ExecuteTaskResponseCommand() {
}
public ExecuteTaskResponseCommand(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
/**
* task instance id
*/
private int taskInstanceId;
/**
* status
*/
private int status;
/**
* end time
*/
private Date endTime;
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
kd">public int getTaskInstanceId() {
}
kd">public int getTaskInstanceId() {
kd">public int getTaskInstanceId() {
kd">public int getTaskInstanceId() {
return taskInstanceId;
}
kd">public int getTaskInstanceId() {
}
kd">public int getTaskInstanceId() {
}
kd">public int getTaskInstanceId() {
public void setTaskInstanceId(int taskInstanceId) {
kd">public int getTaskInstanceId() {
this.taskInstanceId = taskInstanceId;
kd">public int getTaskInstanceId() {
public int getStatus() {
kd">public int getTaskInstanceId() {
return status;
kd">public int getTaskInstanceId() {
public void setStatus(int status) {
return taskInstanceId;
return taskInstanceId;
kd">public int getTaskInstanceId() {
byte[] body = FastJsonSerializer.serialize(this);
return taskInstanceId;
}
return taskInstanceId;
}
return taskInstanceId;
public void setTaskInstanceId(int taskInstanceId) {
return taskInstanceId;
this.taskInstanceId = taskInstanceId;
return taskInstanceId;
public int getStatus() {
return taskInstanceId;
return status;
return taskInstanceId;
public void setStatus(int status) {
}
+
'}';
}
} |
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
import java.util.Date;
/**
* execute task response command
*/
public class ExecuteTaskResponseCommand implements Serializable {
public ExecuteTaskResponseCommand() {
}
public ExecuteTaskResponseCommand(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
/**
* task instance id
*/
private int taskInstanceId;
/**
* status
*/
private int status;
/**
* end time
*/
private Date endTime;
}
kd">public int getTaskInstanceId() {
}
return taskInstanceId;
}
}
}
}
public void setTaskInstanceId(int taskInstanceId) {
}
this.taskInstanceId = taskInstanceId;
}
public int getStatus() {
*/
}
return status;
}
public void setTaskInstanceId(int taskInstanceId) {
}
public void setStatus(int status) {
}
}
public void setTaskInstanceId(int taskInstanceId) {
return taskInstanceId;
this.taskInstanceId = taskInstanceId;
kd">public int getTaskInstanceId() {
public int getStatus() {
return status;
kd">public int getTaskInstanceId() {
public void setStatus(int status) {
this.status = status;
kd">public int getTaskInstanceId() {
}
public void setTaskInstanceId(int taskInstanceId) {
return status;
return endTime;
kd">public int getTaskInstanceId() {
}
public void setTaskInstanceId(int taskInstanceId) {
public void setEndTime(Date endTime) {
public void setTaskInstanceId(int taskInstanceId) {
kd">public int getTaskInstanceId() {
kd">public int getTaskInstanceId() {
}
public void setTaskInstanceId(int taskInstanceId) {
public int getProcessId() {
return processId;
kd">public int getTaskInstanceId() {
}
public void setTaskInstanceId(int taskInstanceId) {
public void setProcessId(int processId) {
this.processId = processId;
kd">public int getTaskInstanceId() {
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
public void setTaskInstanceId(int taskInstanceId) {
public int getStatus() {
kd">public int getTaskInstanceId() {
public void setTaskInstanceId(int taskInstanceId) {
return status;
this.appIds = appIds;
kd">public int getTaskInstanceId() {
/**
this.taskInstanceId = taskInstanceId;
this.taskInstanceId = taskInstanceId;
kd">public int getTaskInstanceId() {
}
}
this.taskInstanceId = taskInstanceId;
return taskInstanceId;
this.taskInstanceId = taskInstanceId;
}
this.taskInstanceId = taskInstanceId;
this.taskInstanceId = taskInstanceId;
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
this.taskInstanceId = taskInstanceId;
this.taskInstanceId = taskInstanceId;
public int getStatus() {
}
this.taskInstanceId = taskInstanceId;
return status;
public String toString() {
return "ExecuteTaskResponseCommand{" +
"taskInstanceId=" + taskInstanceId +
public int getStatus() {
return taskInstanceId;
public int getStatus() {
}
", processId=" + processId +
", appIds='" + appIds + '\'' +
'}';
}
} |
@ -1 +1 @@ |
|||||||
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
/**
* kill task request command
*/
public class KillTaskRequestCommand implements Serializable {
private int taskInstanceId;
private int processId;
private String host;
private String tenantCode;
private String logPath;
private String executePath;
public String getLogPath() {
return logPath;
}
public void setLogPath(String logPath) {
this.logPath = logPath;
}
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public int getProcessId() {
return processId;
}
public void setProcessId(int processId) {
this.processId = processId;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getTenantCode() {
return tenantCode;
}
public void setTenantCode(String tenantCode) {
this.tenantCode = tenantCode;
}
public String getExecutePath() {
return executePath;
}
public void setExecutePath(String executePath) {
this.executePath = executePath;
}
/**
* package request command
*
* @return command
*/
public Command convert2Command(){
Command command = new Command();
command.setType(CommandType.KILL_TASK_REQUEST);
byte[] body = FastJsonSerializer.serialize(this);
command.setBody(body);
return command;
}
} |
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
/**
* kill task request command
*/
public class KillTaskRequestCommand implements Serializable {
/**
* taskInstanceId
*/
kd">private int taskInstanceId;
kd">private int taskInstanceId;
kd">private int taskInstanceId;
kd">private int taskInstanceId;
private int processId;
kd">private int taskInstanceId;
private String host;
*/
kd">private int taskInstanceId;
private String tenantCode;
kd">private int taskInstanceId;
/**
kd">private int taskInstanceId;
private String logPath;
*/
kd">private int taskInstanceId;
/**
* tenantCode
*/
private String tenantCode;
/**
* logPath
*/
private String logPath;
/**
* executePath
*/
private String executePath;
public String getLogPath() {
return logPath;
}
public void setLogPath(String logPath) {
this.logPath = logPath;
}
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public int getProcessId() {
return processId;
}
public void setProcessId(int processId) {
this.processId = processId;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getTenantCode() {
return tenantCode;
}
public void setTenantCode(String tenantCode) {
this.tenantCode = tenantCode;
}
public String getExecutePath() {
return executePath;
}
public void setExecutePath(String executePath) {
this.executePath = executePath;
}
/**
* package request command
*
* @return command
*/
public Command convert2Command(){
Command command = new Command();
command.setType(CommandType.KILL_TASK_REQUEST);
byte[] body = FastJsonSerializer.serialize(this);
command.setBody(body);
return command;
}
} |
@ -0,0 +1 @@ |
|||||||
|
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.remote.command;
import org.apache.dolphinscheduler.remote.utils.FastJsonSerializer;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* kill task response command
*/
public class KillTaskResponseCommand implements Serializable {
/**
* taskInstanceId
*/
private int taskInstanceId;
/**
* host
*/
private String host;
/**
* status
*/
private int status;
/**
* processId
*/
private int processId;
/**
* other resource manager appId , for example : YARN etc
*/
protected List<String> appIds;
public int getTaskInstanceId() {
return taskInstanceId;
}
public void setTaskInstanceId(int taskInstanceId) {
this.taskInstanceId = taskInstanceId;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getProcessId() {
return processId;
}
public void setProcessId(int processId) {
this.processId = processId;
}
public List<String> getAppIds() {
return appIds;
}
public void setAppIds(List<String> appIds) {
this.appIds = appIds;
}
/**
* package request command
*
* @return command
*/
public Command convert2Command(){
Command command = new Command();
command.setType(CommandType.KILL_TASK_RESPONSE);
byte[] body = FastJsonSerializer.serialize(this);
command.setBody(body);
return command;
}
@Override
public String toString() {
return "KillTaskResponseCommand{" +
"taskInstanceId=" + taskInstanceId +
", host='" + host + '\'' +
", status=" + status +
", processId=" + processId +
", appIds=" + appIds +
'}';
}
} |
@ -0,0 +1,48 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.cache; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.dao.entity.TaskInstance; |
||||||
|
import org.apache.dolphinscheduler.remote.entity.TaskExecutionContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* TaskExecutionContextCacheManager |
||||||
|
*/ |
||||||
|
public interface TaskExecutionContextCacheManager { |
||||||
|
|
||||||
|
/** |
||||||
|
* get taskInstance by taskInstance id |
||||||
|
* |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
* @return taskInstance |
||||||
|
*/ |
||||||
|
TaskExecutionContext getByTaskInstanceId(Integer taskInstanceId); |
||||||
|
|
||||||
|
/** |
||||||
|
* cache taskInstance |
||||||
|
* |
||||||
|
* @param taskExecutionContext taskExecutionContext |
||||||
|
*/ |
||||||
|
void cacheTaskExecutionContext(TaskExecutionContext taskExecutionContext); |
||||||
|
|
||||||
|
/** |
||||||
|
* remove taskInstance by taskInstanceId |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
*/ |
||||||
|
void removeByTaskInstanceId(Integer taskInstanceId); |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.cache.impl; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.remote.entity.TaskExecutionContext; |
||||||
|
import org.apache.dolphinscheduler.server.worker.cache.TaskExecutionContextCacheManager; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* TaskExecutionContextCache |
||||||
|
*/ |
||||||
|
public class TaskExecutionContextCacheManagerImpl implements TaskExecutionContextCacheManager { |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* taskInstance caceh |
||||||
|
*/ |
||||||
|
private Map<Integer,TaskExecutionContext> taskExecutionContextCache = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* get taskInstance by taskInstance id |
||||||
|
* |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
* @return taskInstance |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public TaskExecutionContext getByTaskInstanceId(Integer taskInstanceId) { |
||||||
|
return taskExecutionContextCache.get(taskInstanceId); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* cache taskInstance |
||||||
|
* |
||||||
|
* @param taskExecutionContext taskExecutionContext |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void cacheTaskExecutionContext(TaskExecutionContext taskExecutionContext) { |
||||||
|
taskExecutionContextCache.put(taskExecutionContext.getTaskInstanceId(),taskExecutionContext); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* remove taskInstance by taskInstanceId |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void removeByTaskInstanceId(Integer taskInstanceId) { |
||||||
|
taskExecutionContextCache.remove(taskInstanceId); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.processor; |
||||||
|
|
||||||
|
|
||||||
|
import io.netty.channel.Channel; |
||||||
|
import io.netty.channel.ChannelFuture; |
||||||
|
import io.netty.channel.ChannelFutureListener; |
||||||
|
import org.apache.dolphinscheduler.remote.NettyRemotingClient; |
||||||
|
import org.apache.dolphinscheduler.remote.command.ExecuteTaskAckCommand; |
||||||
|
import org.apache.dolphinscheduler.remote.command.ExecuteTaskResponseCommand; |
||||||
|
import org.apache.dolphinscheduler.remote.command.KillTaskResponseCommand; |
||||||
|
import org.apache.dolphinscheduler.remote.config.NettyClientConfig; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* taks callback service |
||||||
|
*/ |
||||||
|
public class KillTaskCallbackService { |
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(KillTaskCallbackService.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* remote channels |
||||||
|
*/ |
||||||
|
private static final ConcurrentHashMap<Integer, NettyRemoteChannel> REMOTE_CHANNELS = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* netty remoting client |
||||||
|
*/ |
||||||
|
private final NettyRemotingClient nettyRemotingClient; |
||||||
|
|
||||||
|
|
||||||
|
public KillTaskCallbackService(){ |
||||||
|
final NettyClientConfig clientConfig = new NettyClientConfig(); |
||||||
|
this.nettyRemotingClient = new NettyRemotingClient(clientConfig); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* add callback channel |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
* @param channel channel |
||||||
|
*/ |
||||||
|
public void addRemoteChannel(int taskInstanceId, NettyRemoteChannel channel){ |
||||||
|
REMOTE_CHANNELS.put(taskInstanceId, channel); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get callback channel |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
* @return callback channel |
||||||
|
*/ |
||||||
|
public NettyRemoteChannel getRemoteChannel(int taskInstanceId){ |
||||||
|
NettyRemoteChannel nettyRemoteChannel = REMOTE_CHANNELS.get(taskInstanceId); |
||||||
|
if(nettyRemoteChannel.isActive()){ |
||||||
|
return nettyRemoteChannel; |
||||||
|
} |
||||||
|
Channel newChannel = nettyRemotingClient.getChannel(nettyRemoteChannel.getHost()); |
||||||
|
if(newChannel != null){ |
||||||
|
NettyRemoteChannel remoteChannel = new NettyRemoteChannel(newChannel, nettyRemoteChannel.getOpaque()); |
||||||
|
addRemoteChannel(taskInstanceId, remoteChannel); |
||||||
|
return remoteChannel; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* remove callback channels |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
*/ |
||||||
|
public void remove(int taskInstanceId){ |
||||||
|
REMOTE_CHANNELS.remove(taskInstanceId); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* send result |
||||||
|
* |
||||||
|
* @param taskInstanceId taskInstanceId |
||||||
|
* @param killTaskResponseCommand killTaskResponseCommand |
||||||
|
*/ |
||||||
|
public void sendKillResult(int taskInstanceId, KillTaskResponseCommand killTaskResponseCommand){ |
||||||
|
NettyRemoteChannel nettyRemoteChannel = getRemoteChannel(taskInstanceId); |
||||||
|
if(nettyRemoteChannel == null){ |
||||||
|
//TODO
|
||||||
|
} else{ |
||||||
|
nettyRemoteChannel.writeAndFlush(killTaskResponseCommand.convert2Command()).addListener(new ChannelFutureListener(){ |
||||||
|
|
||||||
|
@Override |
||||||
|
public void operationComplete(ChannelFuture future) throws Exception { |
||||||
|
if(future.isSuccess()){ |
||||||
|
remove(taskInstanceId); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,365 +0,0 @@ |
|||||||
/* |
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
||||||
* contributor license agreements. See the NOTICE file distributed with |
|
||||||
* this work for additional information regarding copyright ownership. |
|
||||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.runner; |
|
||||||
|
|
||||||
import org.apache.curator.framework.recipes.locks.InterProcessMutex; |
|
||||||
import org.apache.dolphinscheduler.common.Constants; |
|
||||||
import org.apache.dolphinscheduler.common.enums.ExecutionStatus; |
|
||||||
import org.apache.dolphinscheduler.common.thread.Stopper; |
|
||||||
import org.apache.dolphinscheduler.common.thread.ThreadUtils; |
|
||||||
import org.apache.dolphinscheduler.common.utils.*; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.TaskInstance; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.Tenant; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.WorkerGroup; |
|
||||||
import org.apache.dolphinscheduler.server.worker.config.WorkerConfig; |
|
||||||
import org.apache.dolphinscheduler.server.zk.ZKWorkerClient; |
|
||||||
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; |
|
||||||
import org.apache.dolphinscheduler.service.process.ProcessService; |
|
||||||
import org.apache.dolphinscheduler.service.queue.ITaskQueue; |
|
||||||
import org.apache.dolphinscheduler.service.zk.AbstractZKClient; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.util.Arrays; |
|
||||||
import java.util.Date; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.ExecutorService; |
|
||||||
import java.util.concurrent.ThreadPoolExecutor; |
|
||||||
|
|
||||||
/** |
|
||||||
* fetch task thread |
|
||||||
*/ |
|
||||||
public class FetchTaskThread implements Runnable{ |
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FetchTaskThread.class); |
|
||||||
/** |
|
||||||
* set worker concurrent tasks |
|
||||||
*/ |
|
||||||
private final int taskNum; |
|
||||||
|
|
||||||
/** |
|
||||||
* zkWorkerClient |
|
||||||
*/ |
|
||||||
private final ZKWorkerClient zkWorkerClient; |
|
||||||
|
|
||||||
/** |
|
||||||
* task queue impl |
|
||||||
*/ |
|
||||||
protected ITaskQueue taskQueue; |
|
||||||
|
|
||||||
/** |
|
||||||
* process database access |
|
||||||
*/ |
|
||||||
private final ProcessService processService; |
|
||||||
|
|
||||||
/** |
|
||||||
* worker thread pool executor |
|
||||||
*/ |
|
||||||
private final ExecutorService workerExecService; |
|
||||||
|
|
||||||
/** |
|
||||||
* worker exec nums |
|
||||||
*/ |
|
||||||
private int workerExecNums; |
|
||||||
|
|
||||||
/** |
|
||||||
* task instance |
|
||||||
*/ |
|
||||||
private TaskInstance taskInstance; |
|
||||||
|
|
||||||
/** |
|
||||||
* task instance id |
|
||||||
*/ |
|
||||||
Integer taskInstId; |
|
||||||
|
|
||||||
/** |
|
||||||
* worker config |
|
||||||
*/ |
|
||||||
private WorkerConfig workerConfig; |
|
||||||
|
|
||||||
public FetchTaskThread(ZKWorkerClient zkWorkerClient, |
|
||||||
ProcessService processService, |
|
||||||
ITaskQueue taskQueue){ |
|
||||||
this.zkWorkerClient = zkWorkerClient; |
|
||||||
this.processService = processService; |
|
||||||
this.taskQueue = taskQueue; |
|
||||||
this.workerConfig = SpringApplicationContext.getBean(WorkerConfig.class); |
|
||||||
this.taskNum = workerConfig.getWorkerFetchTaskNum(); |
|
||||||
this.workerExecNums = workerConfig.getWorkerExecThreads(); |
|
||||||
// worker thread pool executor
|
|
||||||
this.workerExecService = ThreadUtils.newDaemonFixedThreadExecutor("Worker-Fetch-Task-Thread", workerExecNums); |
|
||||||
this.taskInstance = null; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Check if the task runs on this worker |
|
||||||
* @param taskInstance |
|
||||||
* @param host |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
private boolean checkWorkerGroup(TaskInstance taskInstance, String host){ |
|
||||||
|
|
||||||
int taskWorkerGroupId = processService.getTaskWorkerGroupId(taskInstance); |
|
||||||
|
|
||||||
if(taskWorkerGroupId <= 0){ |
|
||||||
return true; |
|
||||||
} |
|
||||||
WorkerGroup workerGroup = processService.queryWorkerGroupById(taskWorkerGroupId); |
|
||||||
if(workerGroup == null ){ |
|
||||||
logger.info("task {} cannot find the worker group, use all worker instead.", taskInstance.getId()); |
|
||||||
return true; |
|
||||||
} |
|
||||||
String ips = workerGroup.getIpList(); |
|
||||||
if(StringUtils.isBlank(ips)){ |
|
||||||
logger.error("task:{} worker group:{} parameters(ip_list) is null, this task would be running on all workers", |
|
||||||
taskInstance.getId(), workerGroup.getId()); |
|
||||||
} |
|
||||||
String[] ipArray = ips.split(Constants.COMMA); |
|
||||||
List<String> ipList = Arrays.asList(ipArray); |
|
||||||
return ipList.contains(host); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
logger.info("worker start fetch tasks..."); |
|
||||||
while (Stopper.isRunning()){ |
|
||||||
InterProcessMutex mutex = null; |
|
||||||
String currentTaskQueueStr = null; |
|
||||||
try { |
|
||||||
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) workerExecService; |
|
||||||
//check memory and cpu usage and threads
|
|
||||||
boolean runCheckFlag = OSUtils.checkResource(workerConfig.getWorkerMaxCpuloadAvg(), workerConfig.getWorkerReservedMemory()) && checkThreadCount(poolExecutor); |
|
||||||
|
|
||||||
if(!runCheckFlag) { |
|
||||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
//whether have tasks, if no tasks , no need lock //get all tasks
|
|
||||||
boolean hasTask = taskQueue.hasTask(Constants.DOLPHINSCHEDULER_TASKS_QUEUE); |
|
||||||
|
|
||||||
if (!hasTask){ |
|
||||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS); |
|
||||||
continue; |
|
||||||
} |
|
||||||
// creating distributed locks, lock path /dolphinscheduler/lock/worker
|
|
||||||
mutex = zkWorkerClient.acquireZkLock(zkWorkerClient.getZkClient(), |
|
||||||
zkWorkerClient.getWorkerLockPath()); |
|
||||||
|
|
||||||
|
|
||||||
// task instance id str
|
|
||||||
List<String> taskQueueStrArr = taskQueue.poll(Constants.DOLPHINSCHEDULER_TASKS_QUEUE, taskNum); |
|
||||||
|
|
||||||
for(String taskQueueStr : taskQueueStrArr){ |
|
||||||
|
|
||||||
currentTaskQueueStr = taskQueueStr; |
|
||||||
|
|
||||||
if (StringUtils.isEmpty(taskQueueStr)) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (!checkThreadCount(poolExecutor)) { |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
// get task instance id
|
|
||||||
taskInstId = getTaskInstanceId(taskQueueStr); |
|
||||||
|
|
||||||
// mainly to wait for the master insert task to succeed
|
|
||||||
waitForTaskInstance(); |
|
||||||
|
|
||||||
taskInstance = processService.getTaskInstanceDetailByTaskId(taskInstId); |
|
||||||
|
|
||||||
// verify task instance is null
|
|
||||||
if (verifyTaskInstanceIsNull(taskInstance)) { |
|
||||||
logger.warn("remove task queue : {} due to taskInstance is null", taskQueueStr); |
|
||||||
processErrorTask(taskQueueStr); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if(!checkWorkerGroup(taskInstance, OSUtils.getHost())){ |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
// if process definition is null ,process definition already deleted
|
|
||||||
int userId = taskInstance.getProcessDefine() == null ? 0 : taskInstance.getProcessDefine().getUserId(); |
|
||||||
|
|
||||||
Tenant tenant = processService.getTenantForProcess( |
|
||||||
taskInstance.getProcessInstance().getTenantId(), |
|
||||||
userId); |
|
||||||
|
|
||||||
// verify tenant is null
|
|
||||||
if (verifyTenantIsNull(tenant)) { |
|
||||||
logger.warn("remove task queue : {} due to tenant is null", taskQueueStr); |
|
||||||
processErrorTask(taskQueueStr); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
// set queue for process instance, user-specified queue takes precedence over tenant queue
|
|
||||||
String userQueue = processService.queryUserQueueByProcessInstanceId(taskInstance.getProcessInstanceId()); |
|
||||||
taskInstance.getProcessInstance().setQueue(StringUtils.isEmpty(userQueue) ? tenant.getQueue() : userQueue); |
|
||||||
taskInstance.getProcessInstance().setTenantCode(tenant.getTenantCode()); |
|
||||||
|
|
||||||
logger.info("worker fetch taskId : {} from queue ", taskInstId); |
|
||||||
|
|
||||||
// local execute path
|
|
||||||
String execLocalPath = getExecLocalPath(); |
|
||||||
|
|
||||||
logger.info("task instance local execute path : {} ", execLocalPath); |
|
||||||
|
|
||||||
// init task
|
|
||||||
taskInstance.init(OSUtils.getHost(), |
|
||||||
new Date(), |
|
||||||
execLocalPath); |
|
||||||
|
|
||||||
// check and create users
|
|
||||||
FileUtils.createWorkDirAndUserIfAbsent(execLocalPath, |
|
||||||
tenant.getTenantCode()); |
|
||||||
|
|
||||||
logger.info("task : {} ready to submit to task scheduler thread",taskInstId); |
|
||||||
// submit task
|
|
||||||
// workerExecService.submit(new TaskExecuteThread(taskInstance, processService));
|
|
||||||
|
|
||||||
// remove node from zk
|
|
||||||
removeNodeFromTaskQueue(taskQueueStr); |
|
||||||
} |
|
||||||
|
|
||||||
}catch (Exception e){ |
|
||||||
processErrorTask(currentTaskQueueStr); |
|
||||||
logger.error("fetch task thread failure" ,e); |
|
||||||
}finally { |
|
||||||
AbstractZKClient.releaseMutex(mutex); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* process error task |
|
||||||
* |
|
||||||
* @param taskQueueStr task queue str |
|
||||||
*/ |
|
||||||
private void processErrorTask(String taskQueueStr){ |
|
||||||
// remove from zk
|
|
||||||
removeNodeFromTaskQueue(taskQueueStr); |
|
||||||
|
|
||||||
if (taskInstance != null){ |
|
||||||
processService.changeTaskState(ExecutionStatus.FAILURE, |
|
||||||
taskInstance.getStartTime(), |
|
||||||
taskInstance.getHost(), |
|
||||||
null, |
|
||||||
null, |
|
||||||
taskInstId); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* remove node from task queue |
|
||||||
* |
|
||||||
* @param taskQueueStr task queue |
|
||||||
*/ |
|
||||||
private void removeNodeFromTaskQueue(String taskQueueStr){ |
|
||||||
taskQueue.removeNode(Constants.DOLPHINSCHEDULER_TASKS_QUEUE, taskQueueStr); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* verify task instance is null |
|
||||||
* @param taskInstance |
|
||||||
* @return true if task instance is null |
|
||||||
*/ |
|
||||||
private boolean verifyTaskInstanceIsNull(TaskInstance taskInstance) { |
|
||||||
if (taskInstance == null ) { |
|
||||||
logger.error("task instance is null. task id : {} ", taskInstId); |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* verify tenant is null |
|
||||||
* |
|
||||||
* @param tenant tenant |
|
||||||
* @return true if tenant is null |
|
||||||
*/ |
|
||||||
private boolean verifyTenantIsNull(Tenant tenant) { |
|
||||||
if(tenant == null){ |
|
||||||
logger.error("tenant not exists,process instance id : {},task instance id : {}", |
|
||||||
taskInstance.getProcessInstance().getId(), |
|
||||||
taskInstance.getId()); |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get execute local path |
|
||||||
* |
|
||||||
* @return execute local path |
|
||||||
*/ |
|
||||||
private String getExecLocalPath(){ |
|
||||||
return FileUtils.getProcessExecDir(taskInstance.getProcessDefine().getProjectId(), |
|
||||||
taskInstance.getProcessDefine().getId(), |
|
||||||
taskInstance.getProcessInstance().getId(), |
|
||||||
taskInstance.getId()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* check thread count |
|
||||||
* |
|
||||||
* @param poolExecutor pool executor |
|
||||||
* @return true if active count < worker exec nums |
|
||||||
*/ |
|
||||||
private boolean checkThreadCount(ThreadPoolExecutor poolExecutor) { |
|
||||||
int activeCount = poolExecutor.getActiveCount(); |
|
||||||
if (activeCount >= workerExecNums) { |
|
||||||
logger.info("thread insufficient , activeCount : {} , " + |
|
||||||
"workerExecNums : {}, will sleep : {} millis for thread resource", |
|
||||||
activeCount, |
|
||||||
workerExecNums, |
|
||||||
Constants.SLEEP_TIME_MILLIS); |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* wait for task instance exists, because of db action would be delayed. |
|
||||||
* |
|
||||||
* @throws Exception exception |
|
||||||
*/ |
|
||||||
private void waitForTaskInstance()throws Exception{ |
|
||||||
int retryTimes = 30; |
|
||||||
while (taskInstance == null && retryTimes > 0) { |
|
||||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS); |
|
||||||
taskInstance = processService.findTaskInstanceById(taskInstId); |
|
||||||
retryTimes--; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get task instance id |
|
||||||
* |
|
||||||
* @param taskQueueStr task queue |
|
||||||
* @return task instance id |
|
||||||
*/ |
|
||||||
private int getTaskInstanceId(String taskQueueStr){ |
|
||||||
return Integer.parseInt(taskQueueStr.split(Constants.UNDERLINE)[3]); |
|
||||||
} |
|
||||||
} |
|
@ -1,237 +0,0 @@ |
|||||||
/* |
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
||||||
* contributor license agreements. See the NOTICE file distributed with |
|
||||||
* this work for additional information regarding copyright ownership. |
|
||||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.task.dependent; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.common.Constants; |
|
||||||
import org.apache.dolphinscheduler.common.enums.DependResult; |
|
||||||
import org.apache.dolphinscheduler.common.enums.DependentRelation; |
|
||||||
import org.apache.dolphinscheduler.common.enums.ExecutionStatus; |
|
||||||
import org.apache.dolphinscheduler.common.model.DateInterval; |
|
||||||
import org.apache.dolphinscheduler.common.model.DependentItem; |
|
||||||
import org.apache.dolphinscheduler.common.utils.DependentUtils; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.ProcessInstance; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.TaskInstance; |
|
||||||
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; |
|
||||||
import org.apache.dolphinscheduler.service.process.ProcessService; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.util.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* dependent item execute |
|
||||||
*/ |
|
||||||
public class DependentExecute { |
|
||||||
/** |
|
||||||
* process service |
|
||||||
*/ |
|
||||||
private final ProcessService processService = SpringApplicationContext.getBean(ProcessService.class); |
|
||||||
|
|
||||||
/** |
|
||||||
* depend item list |
|
||||||
*/ |
|
||||||
private List<DependentItem> dependItemList; |
|
||||||
|
|
||||||
/** |
|
||||||
* dependent relation |
|
||||||
*/ |
|
||||||
private DependentRelation relation; |
|
||||||
|
|
||||||
/** |
|
||||||
* depend result |
|
||||||
*/ |
|
||||||
private DependResult modelDependResult = DependResult.WAITING; |
|
||||||
|
|
||||||
/** |
|
||||||
* depend result map |
|
||||||
*/ |
|
||||||
private Map<String, DependResult> dependResultMap = new HashMap<>(); |
|
||||||
|
|
||||||
/** |
|
||||||
* logger |
|
||||||
*/ |
|
||||||
private Logger logger = LoggerFactory.getLogger(DependentExecute.class); |
|
||||||
|
|
||||||
/** |
|
||||||
* constructor |
|
||||||
* @param itemList item list |
|
||||||
* @param relation relation |
|
||||||
*/ |
|
||||||
public DependentExecute(List<DependentItem> itemList, DependentRelation relation){ |
|
||||||
this.dependItemList = itemList; |
|
||||||
this.relation = relation; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get dependent item for one dependent item |
|
||||||
* @param dependentItem dependent item |
|
||||||
* @param currentTime current time |
|
||||||
* @return DependResult |
|
||||||
*/ |
|
||||||
public DependResult getDependentResultForItem(DependentItem dependentItem, Date currentTime){ |
|
||||||
List<DateInterval> dateIntervals = DependentUtils.getDateIntervalList(currentTime, dependentItem.getDateValue()); |
|
||||||
return calculateResultForTasks(dependentItem, dateIntervals ); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* calculate dependent result for one dependent item. |
|
||||||
* @param dependentItem dependent item |
|
||||||
* @param dateIntervals date intervals |
|
||||||
* @return dateIntervals |
|
||||||
*/ |
|
||||||
private DependResult calculateResultForTasks(DependentItem dependentItem, |
|
||||||
List<DateInterval> dateIntervals) { |
|
||||||
DependResult result = DependResult.FAILED; |
|
||||||
for(DateInterval dateInterval : dateIntervals){ |
|
||||||
ProcessInstance processInstance = findLastProcessInterval(dependentItem.getDefinitionId(), |
|
||||||
dateInterval); |
|
||||||
if(processInstance == null){ |
|
||||||
logger.error("cannot find the right process instance: definition id:{}, start:{}, end:{}", |
|
||||||
dependentItem.getDefinitionId(), dateInterval.getStartTime(), dateInterval.getEndTime() ); |
|
||||||
return DependResult.FAILED; |
|
||||||
} |
|
||||||
if(dependentItem.getDepTasks().equals(Constants.DEPENDENT_ALL)){ |
|
||||||
result = getDependResultByState(processInstance.getState()); |
|
||||||
}else{ |
|
||||||
TaskInstance taskInstance = null; |
|
||||||
List<TaskInstance> taskInstanceList = processService.findValidTaskListByProcessId(processInstance.getId()); |
|
||||||
|
|
||||||
for(TaskInstance task : taskInstanceList){ |
|
||||||
if(task.getName().equals(dependentItem.getDepTasks())){ |
|
||||||
taskInstance = task; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if(taskInstance == null){ |
|
||||||
// cannot find task in the process instance
|
|
||||||
// maybe because process instance is running or failed.
|
|
||||||
result = getDependResultByState(processInstance.getState()); |
|
||||||
}else{ |
|
||||||
result = getDependResultByState(taskInstance.getState()); |
|
||||||
} |
|
||||||
} |
|
||||||
if(result != DependResult.SUCCESS){ |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* find the last one process instance that : |
|
||||||
* 1. manual run and finish between the interval |
|
||||||
* 2. schedule run and schedule time between the interval |
|
||||||
* @param definitionId definition id |
|
||||||
* @param dateInterval date interval |
|
||||||
* @return ProcessInstance |
|
||||||
*/ |
|
||||||
private ProcessInstance findLastProcessInterval(int definitionId, DateInterval dateInterval) { |
|
||||||
|
|
||||||
ProcessInstance runningProcess = processService.findLastRunningProcess(definitionId, dateInterval); |
|
||||||
if(runningProcess != null){ |
|
||||||
return runningProcess; |
|
||||||
} |
|
||||||
|
|
||||||
ProcessInstance lastSchedulerProcess = processService.findLastSchedulerProcessInterval( |
|
||||||
definitionId, dateInterval |
|
||||||
); |
|
||||||
|
|
||||||
ProcessInstance lastManualProcess = processService.findLastManualProcessInterval( |
|
||||||
definitionId, dateInterval |
|
||||||
); |
|
||||||
|
|
||||||
if(lastManualProcess ==null){ |
|
||||||
return lastSchedulerProcess; |
|
||||||
} |
|
||||||
if(lastSchedulerProcess == null){ |
|
||||||
return lastManualProcess; |
|
||||||
} |
|
||||||
|
|
||||||
return (lastManualProcess.getEndTime().after(lastSchedulerProcess.getEndTime()))? |
|
||||||
lastManualProcess : lastSchedulerProcess; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get dependent result by task/process instance state |
|
||||||
* @param state state |
|
||||||
* @return DependResult |
|
||||||
*/ |
|
||||||
private DependResult getDependResultByState(ExecutionStatus state) { |
|
||||||
|
|
||||||
if(state.typeIsRunning() || state == ExecutionStatus.SUBMITTED_SUCCESS || state == ExecutionStatus.WAITTING_THREAD){ |
|
||||||
return DependResult.WAITING; |
|
||||||
}else if(state.typeIsSuccess()){ |
|
||||||
return DependResult.SUCCESS; |
|
||||||
}else{ |
|
||||||
return DependResult.FAILED; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* judge depend item finished |
|
||||||
* @param currentTime current time |
|
||||||
* @return boolean |
|
||||||
*/ |
|
||||||
public boolean finish(Date currentTime){ |
|
||||||
if(modelDependResult == DependResult.WAITING){ |
|
||||||
modelDependResult = getModelDependResult(currentTime); |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get model depend result |
|
||||||
* @param currentTime current time |
|
||||||
* @return DependResult |
|
||||||
*/ |
|
||||||
public DependResult getModelDependResult(Date currentTime){ |
|
||||||
|
|
||||||
List<DependResult> dependResultList = new ArrayList<>(); |
|
||||||
|
|
||||||
for(DependentItem dependentItem : dependItemList){ |
|
||||||
DependResult dependResult = getDependResultForItem(dependentItem, currentTime); |
|
||||||
if(dependResult != DependResult.WAITING){ |
|
||||||
dependResultMap.put(dependentItem.getKey(), dependResult); |
|
||||||
} |
|
||||||
dependResultList.add(dependResult); |
|
||||||
} |
|
||||||
modelDependResult = DependentUtils.getDependResultForRelation( |
|
||||||
this.relation, dependResultList |
|
||||||
); |
|
||||||
return modelDependResult; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get dependent item result |
|
||||||
* @param item item |
|
||||||
* @param currentTime current time |
|
||||||
* @return DependResult |
|
||||||
*/ |
|
||||||
public DependResult getDependResultForItem(DependentItem item, Date currentTime){ |
|
||||||
String key = item.getKey(); |
|
||||||
if(dependResultMap.containsKey(key)){ |
|
||||||
return dependResultMap.get(key); |
|
||||||
} |
|
||||||
return getDependentResultForItem(item, currentTime); |
|
||||||
} |
|
||||||
|
|
||||||
public Map<String, DependResult> getDependResultMap(){ |
|
||||||
return dependResultMap; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,191 +0,0 @@ |
|||||||
/* |
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
||||||
* contributor license agreements. See the NOTICE file distributed with |
|
||||||
* this work for additional information regarding copyright ownership. |
|
||||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.worker.task.dependent; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.common.Constants; |
|
||||||
import org.apache.dolphinscheduler.common.enums.DependResult; |
|
||||||
import org.apache.dolphinscheduler.common.enums.ExecutionStatus; |
|
||||||
import org.apache.dolphinscheduler.common.model.DependentTaskModel; |
|
||||||
import org.apache.dolphinscheduler.common.task.AbstractParameters; |
|
||||||
import org.apache.dolphinscheduler.common.task.dependent.DependentParameters; |
|
||||||
import org.apache.dolphinscheduler.common.thread.Stopper; |
|
||||||
import org.apache.dolphinscheduler.common.utils.DependentUtils; |
|
||||||
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
|
||||||
import org.apache.dolphinscheduler.dao.entity.TaskInstance; |
|
||||||
import org.apache.dolphinscheduler.server.worker.task.AbstractTask; |
|
||||||
import org.apache.dolphinscheduler.server.worker.task.TaskProps; |
|
||||||
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; |
|
||||||
import org.apache.dolphinscheduler.service.process.ProcessService; |
|
||||||
import org.slf4j.Logger; |
|
||||||
|
|
||||||
import java.util.*; |
|
||||||
|
|
||||||
import static org.apache.dolphinscheduler.common.Constants.DEPENDENT_SPLIT; |
|
||||||
|
|
||||||
/** |
|
||||||
* Dependent Task |
|
||||||
*/ |
|
||||||
public class DependentTask extends AbstractTask { |
|
||||||
|
|
||||||
/** |
|
||||||
* dependent task list |
|
||||||
*/ |
|
||||||
private List<DependentExecute> dependentTaskList = new ArrayList<>(); |
|
||||||
|
|
||||||
/** |
|
||||||
* depend item result map |
|
||||||
* save the result to log file |
|
||||||
*/ |
|
||||||
private Map<String, DependResult> dependResultMap = new HashMap<>(); |
|
||||||
|
|
||||||
/** |
|
||||||
* dependent parameters |
|
||||||
*/ |
|
||||||
private DependentParameters dependentParameters; |
|
||||||
|
|
||||||
/** |
|
||||||
* dependent date |
|
||||||
*/ |
|
||||||
private Date dependentDate; |
|
||||||
|
|
||||||
/** |
|
||||||
* process service |
|
||||||
*/ |
|
||||||
private ProcessService processService; |
|
||||||
|
|
||||||
/** |
|
||||||
* constructor |
|
||||||
* @param props props |
|
||||||
* @param logger logger |
|
||||||
*/ |
|
||||||
public DependentTask(TaskProps props, Logger logger) { |
|
||||||
super(props, logger); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init(){ |
|
||||||
logger.info("dependent task initialize"); |
|
||||||
|
|
||||||
this.dependentParameters = JSONUtils.parseObject(this.taskProps.getDependence(), |
|
||||||
DependentParameters.class); |
|
||||||
|
|
||||||
for(DependentTaskModel taskModel : dependentParameters.getDependTaskList()){ |
|
||||||
this.dependentTaskList.add(new DependentExecute( |
|
||||||
taskModel.getDependItemList(), taskModel.getRelation())); |
|
||||||
} |
|
||||||
|
|
||||||
this.processService = SpringApplicationContext.getBean(ProcessService.class); |
|
||||||
|
|
||||||
if(taskProps.getScheduleTime() != null){ |
|
||||||
this.dependentDate = taskProps.getScheduleTime(); |
|
||||||
}else{ |
|
||||||
this.dependentDate = taskProps.getTaskStartTime(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void handle() throws Exception { |
|
||||||
// set the name of the current thread
|
|
||||||
String threadLoggerInfoName = String.format(Constants.TASK_LOG_INFO_FORMAT, taskProps.getTaskAppId()); |
|
||||||
Thread.currentThread().setName(threadLoggerInfoName); |
|
||||||
|
|
||||||
try{ |
|
||||||
TaskInstance taskInstance = null; |
|
||||||
while(Stopper.isRunning()){ |
|
||||||
taskInstance = processService.findTaskInstanceById(this.taskProps.getTaskInstanceId()); |
|
||||||
|
|
||||||
if(taskInstance == null){ |
|
||||||
exitStatusCode = -1; |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if(taskInstance.getState() == ExecutionStatus.KILL){ |
|
||||||
this.cancel = true; |
|
||||||
} |
|
||||||
|
|
||||||
if(this.cancel || allDependentTaskFinish()){ |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS); |
|
||||||
} |
|
||||||
|
|
||||||
if(cancel){ |
|
||||||
exitStatusCode = Constants.EXIT_CODE_KILL; |
|
||||||
}else{ |
|
||||||
DependResult result = getTaskDependResult(); |
|
||||||
exitStatusCode = (result == DependResult.SUCCESS) ? |
|
||||||
Constants.EXIT_CODE_SUCCESS : Constants.EXIT_CODE_FAILURE; |
|
||||||
} |
|
||||||
}catch (Exception e){ |
|
||||||
logger.error(e.getMessage(),e); |
|
||||||
exitStatusCode = -1; |
|
||||||
throw e; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* get dependent result |
|
||||||
* @return DependResult |
|
||||||
*/ |
|
||||||
private DependResult getTaskDependResult(){ |
|
||||||
List<DependResult> dependResultList = new ArrayList<>(); |
|
||||||
for(DependentExecute dependentExecute : dependentTaskList){ |
|
||||||
DependResult dependResult = dependentExecute.getModelDependResult(dependentDate); |
|
||||||
dependResultList.add(dependResult); |
|
||||||
} |
|
||||||
DependResult result = DependentUtils.getDependResultForRelation( |
|
||||||
this.dependentParameters.getRelation(), dependResultList |
|
||||||
); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* judge all dependent tasks finish |
|
||||||
* @return whether all dependent tasks finish |
|
||||||
*/ |
|
||||||
private boolean allDependentTaskFinish(){ |
|
||||||
boolean finish = true; |
|
||||||
for(DependentExecute dependentExecute : dependentTaskList){ |
|
||||||
for(Map.Entry<String, DependResult> entry: dependentExecute.getDependResultMap().entrySet()) { |
|
||||||
if(!dependResultMap.containsKey(entry.getKey())){ |
|
||||||
dependResultMap.put(entry.getKey(), entry.getValue()); |
|
||||||
//save depend result to log
|
|
||||||
logger.info("dependent item complete {} {},{}", |
|
||||||
DEPENDENT_SPLIT, entry.getKey(), entry.getValue().toString()); |
|
||||||
} |
|
||||||
} |
|
||||||
if(!dependentExecute.finish(dependentDate)){ |
|
||||||
finish = false; |
|
||||||
} |
|
||||||
} |
|
||||||
return finish; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
public void cancelApplication(boolean cancelApplication) throws Exception { |
|
||||||
// cancel process
|
|
||||||
this.cancel = true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public AbstractParameters getParameters() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue