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

org.jetlinks.rule.engine.defaults.DefaultTask Maven / Gradle / Ivy

The newest version!
package org.jetlinks.rule.engine.defaults;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.jetlinks.core.trace.FluxTracer;
import org.jetlinks.core.trace.MonoTracer;
import org.jetlinks.core.trace.TraceHolder;
import org.jetlinks.rule.engine.api.RuleConstants;
import org.jetlinks.rule.engine.api.RuleData;
import org.jetlinks.rule.engine.api.scheduler.ScheduleJob;
import org.jetlinks.rule.engine.api.task.ExecutableTaskExecutor;
import org.jetlinks.rule.engine.api.task.Task;
import org.jetlinks.rule.engine.api.task.TaskExecutor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class DefaultTask implements Task {

    //工作器ID
    @Getter
    private final String workerId;

    //调度器ID
    @Getter
    private final String schedulerId;

    private final AbstractExecutionContext context;

    private final TaskExecutor executor;

    private long lastStateTime;

    private long startTime;

    private final String id;

    public DefaultTask(String schedulerId,
                       String workerId,
                       AbstractExecutionContext context,
                       TaskExecutor executor) {
        this.schedulerId = schedulerId;
        this.workerId = workerId;
        this.context = context;
        this.executor = executor;
        this.id = DigestUtils.md5Hex(workerId + ":" + context.getInstanceId() + ":" + context.getJob().getNodeId());
        //监听状态切换事件
        executor.onStateChanged((from, to) -> {
            lastStateTime = System.currentTimeMillis();
            Map data = new HashMap<>();
            data.put("from", from.name());
            data.put("to", to.name());
            data.put("taskId", getId());
            data.put("instanceId", context.getInstanceId());
            data.put("nodeId", context.getJob().getNodeId());
            data.put("timestamp", System.currentTimeMillis());
            Flux.merge(
                        context.getEventBus()
                               .publish(RuleConstants.Topics.state(context.getInstanceId(), context
                                       .getJob()
                                       .getNodeId()), data),
                        context.getEventBus()
                               .publish(RuleConstants.Topics.event(context.getInstanceId(), context
                                       .getJob()
                                       .getNodeId(), to.name()), context.newRuleData(data))
                )
                .doOnError(err -> log.error(err.getMessage(), err))
                .subscribe();

        });
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public String getName() {
        return executor.getName();
    }

    /**
     * 获取任务信息
     *
     * @return 任务信息
     */
    @Override
    public ScheduleJob getJob() {
        return context.getJob();
    }

    /**
     * 设置任务信息,用于热更新任务.
     *
     * @param job 任务信息
     * @return empty Mono
     */
    @Override
    public Mono setJob(ScheduleJob job) {
        return Mono.fromRunnable(() -> {
            ScheduleJob old = context.getJob();
            context.setJob(job);
            try {
                executor.validate();
            } catch (Throwable e) {
                context.setJob(old);
                throw e;
            }
        });
    }

    /**
     * 重新加载任务,如果配置发生变化,将重启任务.
     *
     * @return empty Mono
     */
    @Override
    public Mono reload() {
        log.debug("reload task[{}]:[{}]", getId(), getJob());
        return Mono
                .fromRunnable(() -> {
                    context.reload();
                    executor.reload();
                })
                .as(MonoTracer.create(
                        RuleConstants.Trace.reloadNodeSpanName(getJob().getInstanceId(), getJob().getNodeId()),
                        builder -> builder.setAttribute(RuleConstants.Trace.executor, getJob().getExecutor())))
                .subscribeOn(Schedulers.boundedElastic());
    }


    /**
     * 启动,开始执行任务
     *
     * @return empty Mono
     */
    @Override
    public Mono start() {
        log.debug("start task[{}]:[{}]", getId(), getJob());
        return Mono.fromRunnable(executor::start)
                   .doOnSuccess((v) -> startTime = System.currentTimeMillis())
                   .as(MonoTracer.create(
                           RuleConstants.Trace.startNodeSpanName(getJob().getInstanceId(), getJob().getNodeId()),
                           builder -> builder.setAttribute(RuleConstants.Trace.executor, getJob().getExecutor())))
                   .subscribeOn(Schedulers.boundedElastic());
    }

    /**
     * 暂停执行任务
     *
     * @return empty Mono
     */
    @Override
    public Mono pause() {
        log.debug("pause task[{}]:[{}]", getId(), getJob());
        return Mono.fromRunnable(executor::pause);
    }

    /**
     * 停止任务,与暂停不同等的是,停止后将进行清理资源等操作
     *
     * @return empty Mono
     */
    @Override
    public Mono shutdown() {
        log.debug("shutdown task[{}]:[{}]", getId(), getJob());
        return Mono
                .fromRunnable(executor::shutdown)
                .then(Mono.fromRunnable(context::doShutdown))
                .as(MonoTracer.create(
                        RuleConstants.Trace.shutdownNodeSpanName(getJob().getInstanceId(), getJob().getNodeId()),
                        builder -> builder.setAttribute(RuleConstants.Trace.executor, getJob().getExecutor())))
                .subscribeOn(Schedulers.boundedElastic());
    }

    /**
     * 执行任务
     *
     * @return 结果
     */
    @Override
    public Mono execute(RuleData data) {
        log.debug("execute task[{}]:[{}]", getId(), getJob());
        if (executor instanceof ExecutableTaskExecutor) {
            return TraceHolder
                    .writeContextTo(data, RuleData::setHeader)
                    .flatMap(ruleData -> ((ExecutableTaskExecutor) executor).execute(ruleData));
        }
        return Mono.empty();
    }

    /**
     * 获取任务状态
     *
     * @return 状态
     */
    @Override
    public Mono getState() {
        return Mono.just(executor.getState());
    }

    /**
     * 设置debug,开启debug后,会打印更多的日志信息。
     *
     * @param debug 是否开启debug
     * @return empty Mono
     */
    @Override
    public Mono debug(boolean debug) {
        log.debug("set task debug[{}] [{}]:[{}]", debug, getId(), getJob());
        return Mono.fromRunnable(() -> context.setDebug(debug));
    }

    /**
     * @return 上一次状态变更时间
     */
    @Override
    public Mono getLastStateTime() {
        return Mono.just(lastStateTime);
    }

    /**
     * @return 启动时间
     */
    @Override
    public Mono getStartTime() {
        return Mono.just(startTime);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy