All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.dts.client.service.NodeServerServiceImpl Maven / Gradle / Ivy

package com.alibaba.dts.client.service;

import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import com.alibaba.dts.client.executor.grid.unit.FlexibleThreadPoolExecutor;
import org.springframework.util.CollectionUtils;

import com.alibaba.dts.client.executor.grid.queue.receive.TaskReceiveHandler;
import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
import com.alibaba.dts.client.store.access.TaskSnapshotAccess;
import com.alibaba.dts.common.constants.Constants;
import com.alibaba.dts.common.context.InvocationContext;
import com.alibaba.dts.common.domain.ExecutableTask;
import com.alibaba.dts.common.domain.remoting.RemoteMachine;
import com.alibaba.dts.common.domain.result.Result;
import com.alibaba.dts.common.domain.result.ResultCode;
import com.alibaba.dts.common.domain.store.ExecutionCounter;
import com.alibaba.dts.common.domain.store.TaskSnapshot;
import com.alibaba.dts.common.exception.AccessException;
import com.alibaba.dts.common.logger.SchedulerXLoggerFactory;
import com.alibaba.dts.common.logger.innerlog.Logger;
import com.alibaba.dts.common.service.NodeServerService;
import com.alibaba.dts.common.util.NamedThreadFactory;

/**
 * @author Ronan Zhan
 * @date 16/8/30.
 */
public class NodeServerServiceImpl implements NodeServerService {

    private static final Logger logger = SchedulerXLoggerFactory.getLogger(NodeServerServiceImpl.class);

    private final ConcurrentHashMap logTable = new ConcurrentHashMap();

    private ClientContextImpl clientContext;

    private BlockingQueue taskReceiveBuffer;

    TaskReceiveHandler taskReceiveHandler;

    private int bufferSize;

    /**
     * map for job instance and consume thread pool
     */
    private ConcurrentHashMap executorServiceMap
            = new ConcurrentHashMap();

    /**
     * 本机连接的node
     */
    private final ConcurrentHashMap connectToNodes
            = new ConcurrentHashMap();
    /**
     * 连接到本机的node
     */
    private final ConcurrentHashMap connectFromNodes
            = new ConcurrentHashMap();

    public NodeServerServiceImpl(ClientContextImpl clientContext) {
        this.clientContext = clientContext;
    }

    public void init() {
        bufferSize = clientContext.nodeConfig.getReceiveBufferSize();
        taskReceiveBuffer = new ArrayBlockingQueue(bufferSize);
        taskReceiveHandler = new TaskReceiveHandler(clientContext, executorServiceMap);
        taskReceiveHandler.listen(taskReceiveBuffer);
    }

    @Override
    public Result connect() {

        //        RemoteMachine remoteMachine = InvocationContext.acquireRemoteMachine();
        return new Result(true, ResultCode.SUCCESS);
    }

    @Override
    public Result receiveTasks(final ExecutableTask executableTask) {
        try {
            final Long jobInstanceId = executableTask.getJobInstanceSnapshot().getId();

            if (clientContext.getGridJobManager().containsInterruptedJobInstance(jobInstanceId)) {
                logger.warn("[NodeServerService]: receiveTasks force interrupt:"
                        + ",jobId:" + executableTask.getJob().getId()
                        + ",jobInstanceId:" + executableTask.getJobInstanceSnapshot().getId()
                        + ",total tasks:" + executableTask.getTaskSnapshotList().size()
                );
                return new Result(true, ResultCode.FAILURE);
            }

            ExecutorService executorService = executorServiceMap.get(jobInstanceId);
            if (executorService == null) {
                int consumerThreads = this.clientContext.getClientConfig().getConsumerThreads();
                Map consumerThreadsMap = this.clientContext.getClientConfig().getConsumerThreadsMap();
                if (!CollectionUtils.isEmpty(consumerThreadsMap) && consumerThreadsMap.get(
                        executableTask.getJob().getJobProcessor()) != null) {
                    consumerThreads = this.clientContext.getClientConfig().checkConsumerThreads(
                            consumerThreadsMap.get(executableTask.getJob().getJobProcessor()).intValue());
                }
                executorService = new FlexibleThreadPoolExecutor(consumerThreads, consumerThreads, 15, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("SchedulerX-Grid-Task-Processor_" + executableTask.getJob().getId() + "_" + jobInstanceId + "_" + executableTask.getJobInstanceSnapshot().getFireTime() + "#"));
                ExecutorService executorServiceExist = executorServiceMap.putIfAbsent(jobInstanceId, executorService);
                if (executorServiceExist != null) {
                    executorService.shutdownNow();
                }
            }

            boolean publishEventResult = taskReceiveBuffer.offer(executableTask);
            if (publishEventResult) {

                return new Result(true, ResultCode.SUCCESS);
            } else {
                return new Result(false, ResultCode.NODE_RECEIVE_QUEUE_NOT_AVAILABLE);
            }
        } catch (Exception e) {
            logger.error("Job接收错误, {}", executableTask, e);
            return new Result(false);
        }
    }

    /**
     * 任务执行确认
     * 

* taskSnapshot */ @Override public Result acknowledge(TaskSnapshot taskSnapshot) { try { RemoteMachine remoteMachine = InvocationContext.acquireRemoteMachine(); if (taskSnapshot.getStatus() == Constants.TASK_STATUS_SUCCESS || taskSnapshot.getStatus() == Constants.TASK_STATUS_FAILURE && taskSnapshot.getRetryCount() <= 0) { int deletedCount = clientContext.getStore().getTaskSnapshotDao().delete(taskSnapshot); if (deletedCount <= 0) { //indicates that this task snapshot has been acknowledged and this is a redundant ack, // just let it go! return new Result(true); } } else { int rst = clientContext.getStore().getTaskSnapshotDao().taskSnapshotAck(taskSnapshot); if (rst <= 0) { //indicates that this task snapshot has been acknowledged and this is a redundant ack, // just let it go! return new Result(true); } } int status = taskSnapshot.getStatus(); Long jobInstanceId = taskSnapshot.getJobInstanceId(); ConcurrentHashMap> executionCounterMapByReceiveNode = clientContext.getExecutionCounterTable().get(jobInstanceId); if (executionCounterMapByReceiveNode == null) { executionCounterMapByReceiveNode = new ConcurrentHashMap>(); ConcurrentHashMap> executionCounterMapByReceiveNodeExist = clientContext.getExecutionCounterTable().putIfAbsent( jobInstanceId, executionCounterMapByReceiveNode); if (executionCounterMapByReceiveNodeExist != null) { executionCounterMapByReceiveNode = executionCounterMapByReceiveNodeExist; } } String receiveNode = remoteMachine.getRemoteAddress().substring(0, remoteMachine.getRemoteAddress().indexOf(':') + 1) + remoteMachine.getNodeListenPort(); ConcurrentHashMap executionCounterMapByTaskName = executionCounterMapByReceiveNode .get(receiveNode); if (executionCounterMapByTaskName == null) { executionCounterMapByTaskName = new ConcurrentHashMap(); ConcurrentHashMap executionCounterMapByTaskNameExist = executionCounterMapByReceiveNode.putIfAbsent(receiveNode, executionCounterMapByTaskName); if (executionCounterMapByTaskNameExist != null) { executionCounterMapByTaskName = executionCounterMapByTaskNameExist; } } String taskName = taskSnapshot.getTaskName(); ExecutionCounter executionCounter = executionCounterMapByTaskName.get(taskName); if (executionCounter == null) { executionCounter = new ExecutionCounter(); executionCounter.setReceiveNode(receiveNode); executionCounter.setTaskName(taskName); ExecutionCounter executionCounterExist = executionCounterMapByTaskName.putIfAbsent(taskName, executionCounter); if (executionCounterExist != null) { executionCounter = executionCounterExist; } } // if (taskSnapshot.isCompensation()) { //补偿任务 // if (status == Constants.TASK_STATUS_SUCCESS) { // executionCounter.getSuccessCounter().getAndIncrement(); //// executionCounter.getFailCounter().decrementAndGet(); // } else { // executionCounter.getFailCounter().getAndIncrement(); // } // } else { if (status == Constants.TASK_STATUS_SUCCESS) { executionCounter.getSuccessCounter().getAndIncrement(); executionCounter.getQueuedCounter().decrementAndGet(); } else { executionCounter.getFailCounter().getAndIncrement(); executionCounter.getQueuedCounter().decrementAndGet(); } // } return new Result(true); } catch (Throwable t) { logger.error("Task snapshot ack failed, {}", taskSnapshot, t); return new Result(false); } } public boolean stopTask(long jobId, long jobInstanceId) { try { // clientContext.getGridTaskSender().addInterruptedJobInstance(jobInstanceId); clientContext.getGridJobManager().addInterruptedJobInstance(jobInstanceId); // ExecutorService executorService = executorServiceMap.get(jobInstanceId); // if (executorService != null) { // executorServiceMap.remove(jobInstanceId); // executorService.shutdown(); // } clientContext.getGridTaskSender().clearInsertBuffer(jobInstanceId); clientContext.getExecutor().doGridJobCleanTaskForStop(jobInstanceId); //clientContext.getGridTaskSender().addInterruptedJobInstance(jobInstanceId); fixDispatchedTasksStatus(jobInstanceId); return true; } catch (Throwable throwable) { logger.error("failed to stop job, id = {}, jonInstanceId = {}", jobId, jobInstanceId, throwable); return false; } } /** * set status of tasks whose status is not success to fail and retry count as zero *

* jobInstanceId */ private void fixDispatchedTasksStatus(final long jobInstanceId) throws AccessException { //TODO update execution counter // ExecutionCounter executionCounter = clientContext.getExecutionCounterMap().get(jobInstanceId); // executionCounter.getFailCounter().set(executionCounter.getTotalCounter().get() - executionCounter // .getSuccessCounter().get()); // executionCounter.getQueuedCounter().set(0); //TODO detete all tasks associated with the specified job instance id new Thread(new Runnable() { @Override public void run() { boolean stopFlag = false; while (!stopFlag) { try { TimeUnit.SECONDS.sleep(10); long count = clientContext.getStore().getTaskSnapshotDao().deleteByJobInstanceId(jobInstanceId); while (count > 0) { count = clientContext.getStore().getTaskSnapshotDao().deleteByJobInstanceId(jobInstanceId); } stopFlag = true; } catch (Throwable e) { logger.error("deleteByJobInstanceId error", e); stopFlag = false; } } } }).start(); // } public ConcurrentHashMap getExecutorServiceMap() { return executorServiceMap; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy