【问题标题】:Executing dependent tasks in java在java中执行依赖任务
【发布时间】:2023-03-30 00:53:01
【问题描述】:

我需要找到一种方法来执行相互依赖的任务。

  • 第一个任务必须从远程服务器下载一个 zip 文件。
  • 第二个任务的目标是解压第一个任务下载的文件。
  • 第三个任务必须处理从 zip 中提取的文件。

所以,第三个依赖于第二个,第二个依赖于第一个任务。 自然,如果其中一项任务失败,则不应执行其他任务。由于第一个任务从远程服务器下载文件,因此应该有一种重新启动任务的机制,即服务器不可用。 任务必须每天执行。

有任何建议、模式或 java API 吗?

问候!

【问题讨论】:

  • 它们都是相互依赖的,为什么要分开它们?

标签: java concurrency dependencies scheduled-tasks


【解决方案1】:

看来你不想把它们分成任务,就这样吧:

process(unzip(download(uri)));

【讨论】:

  • 是的,这可能是一个任务,有 3 个方法一个接一个地执行。如果服务器不可用,我担心重复下载作业。
  • 然后将 download 重命名为 downloadWithRetries 并让该方法调用 download 几次...
【解决方案2】:

这在一定程度上取决于外部要求。有用户参与吗?监控?警报?...

显然,最简单的方法就是检查前一个是否完成了它应该做的事情。

  1. download() 下载文件到指定位置。
  2. unzip() 如果下载的文件在适当的位置,则将文件提取到指定位置。
  3. process() 处理已提取的数据。

一种更“正式”的方式是使用工作流引擎。根据要求,您可以获得从花哨的 UI 到遵循工作流的正式标准化 .XML 定义的所有功能 - 以及介于两者之间的任何功能。

http://java-source.net/open-source/workflow-engines

【讨论】:

  • 没有用户参与,但如果任务 A 无法下载 zip 文件,发出警报会很有用。
  • 因此您需要确定是否足够简单以编程方式完成所有操作,或者是否需要使用某些工作流引擎。一般来说,我拒绝使用框架,直到拥有一个足够的收益。简单的独立代码更容易维护。
  • 我同意。但是我想到了使用一些java并发api。
  • 那么你打算让其中几个任务并行执行吗?
【解决方案3】:

创建一个公共方法来执行任务的完整链和私有方法:

public void doIt() {
  if (download() == false) {
     // download failed
  } else if (unzip() == false) {
     // unzip failed;
  } else (process() == false)
     // processing failed
  }
}

private boolean download() {/* ... */}
private boolean unzip() {/* ... */}
private boolean process() {/* ... */}

所以你有一个 API 可以保证所有步骤都以正确的顺序执行,并且只有在满足某些条件时才会执行一个步骤(上面的示例只是说明了这种模式)

【讨论】:

    【解决方案4】:

    对于日常执行,您可以使用Quartz Framework

    由于任务相互依赖,我建议评估任务返回的错误代码或异常。如果上一个任务成功则继续。

    【讨论】:

      【解决方案5】:

      执行这些任务的正常方法是;按顺序调用每个任务,并在发生故障时抛出异常,从而阻止执行以下任务。类似的东西

      try {
        download();
        unzip();
        process();
      } catch(Exception failed) {
        failed.printStackTrace();
      }
      

      【讨论】:

      • 这是最简单的方法,实现所有三个方法并将它们放在单个任务中。可以用 java.util.timer
      【解决方案6】:

      我认为您感兴趣的是某种事务定义。

      - 定义TaskA(例如下载)
      - 定义TaskB(例如解压缩)
      - 定义TaskC(例如进程)
      假设您的意图是让任务也独立工作,例如只下载一个文件(不执行TaskB,TaskC)你应该定义Transaction1TaskA,TaskB,TaskC组成或Transaction2仅由TaskA组成。
      语义例如关于 Transaction1,TaskA、TaskB 和 TaskC 应按顺序执行,并且可以在您的事务定义中捕获全部或全部。
      定义可以在 xml 配置文件中,您可以使用框架,例如用于调度的石英。
      更高的构造应检查事务并按定义执行它们。

      【讨论】:

        【解决方案7】:

        使用Dexecutor 可以轻松执行相关任务

        免责声明:我是图书馆的所有者

        基本上你需要以下模式

        使用 Dexecutor.addDependency 方法

         DefaultDexecutor<Integer, Integer> executor = newTaskExecutor();
        //Building
        executor.addDependency(1, 2);
        executor.addDependency(2, 3);
        executor.addDependency(3, 4);
        executor.addDependency(4, 5);
        //Execution
        executor.execute(ExecutionConfig.TERMINATING);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-28
          • 1970-01-01
          • 2013-04-19
          • 2019-09-08
          • 2016-04-22
          • 1970-01-01
          • 2017-05-13
          相关资源
          最近更新 更多