关于通过 webapp 运行 ProcessBuilder 的一些问题

发布于 2024-12-12 13:40:42 字数 507 浏览 0 评论 0原文

我正在编写一个网络应用程序,它基本上允许用户使用通过各种形式输入的参数来启动 shell 脚本。经过一些研究后,我相信 ProcessBuilder 是运行 shell 脚本的最佳方式,但是我需要满足一些条件,并且希望其他人可以告诉我我的想法是否正确。

将启动的脚本实际上可能需要几个小时才能运行。显然我不能让应用程序暂停并等待那么长时间。所以我想知道线程是否是该问题的答案?我对使用线程和寻求一些建议不太有经验。我应该在新线程中启动 ProcessBuilder 以便主 Web 应用程序继续运行吗?这还能用吗?难道只是声明一个新线程并将进程构建器分配给它那么简单吗?我是否需要担心运行或创建各种线程?只是不确定要注意什么或要注意哪些陷阱。

另外,我确实需要一种方法来至少能够在进程运行后检查进程的状态。要求需要某种方式来显示该过程的进度,但我不知道这是否可能。我相信至少能够表明它仍在运行应该是可以接受的。我该如何检测呢?

有关更多信息,它是一个 Java/Spring Web 应用程序,将在某种风格的 Unix 上运行。感谢您的任何想法和帮助。

I'm writing a webapp that basically allows users to kick off shell scripts with parameters they enter through various forms. After doing some research I believe ProcessBuilder to be the best way to run the shell scripts, however I've got some conditions that I need to meet and was hoping some others could tell me if I'm thinking along the correct lines.

The scripts that will be kicked off can literally take a few hours to run. So obviously I can't have the app pause and wait for that long. So I'm wondering if threads is the answer to that problem? I'm not very experienced with using threads and looking for some advice. Should I kick off the ProcessBuilder in a new thread so that the main web app will continue to run? Will that even work? Is it as simple as just declaring a new thread and assigning the process builder to it? Do I have to worry about having various threads running or created? Just not sure of what to be on the look out for or what pitfalls to keep aware of.

Also, I really need a way to be able to at least check on the status of the process once it is running. The requirements call for some way to show how far along the process is, but I don't know that that is possible. I believe being able to at the very least show that it is still running should be acceptable. How would I go about detecting that?

For some more info it's a Java/Spring web app and will be running on some flavor of Unix. Thanks for any thoughts and help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆伤 2024-12-19 13:40:42

您可以实现诸如 JobManagerJob 之类的东西。

Job 可以是一个具有 ProcessBuilderRunnable。在其 run 方法中,它启动进程 (ProcessBuilder.start),等待其退出并在完成时回调 JobManager,可能返回进程的退出状态。

JobManager 创建作业(每个作业都在一个新的线程中),维护当前作业的集合(也许是最近完成的作业的集合,也许失败作业的列表)。客户端可以让 JobManager 作业执行并查询所有作业或特定作业的状态(运行、完成、失败)。

关于进程的状态,作业可以具有 startTime、endTime 和 exitStatus 变量以及关联的 get 方法。您可以将它们返回给客户端以显示作业状态表。

您的 Job.run 方法可能如下所示。

public void run() {
  startTime = System.currentTimeMillis();  
  process = processBuilder.start();

  // spawn threads to consume process output streams
  // even if you're not going to read them

  while (running) {
    try {
      process.waitFor();
      running = false;
    } catch (InterruptedException e) {
      // you could stop a process by interrupting it's Job thread
      process.destroy();
    }
  }
  exitStatus = process.exitValue();
  endTime = System.currentTimeMillis();
  jobManager.onExit(this);
}

关于“完成百分比”,只有当你有某种测量方法时才可能实现。

如果任务应在特定时间内完成,您可以使用它作为报告预期完成时间/完成百分比的粗略方法。

或者,您可以捕获进程的输出,使用它在作业中设置percentComplete 变量。例如,当您在输出中看到“message X”时,设置percentComplete=25%。这意味着为每种类型的脚本实现自定义代码 - 可能是 Job 子类,或者为 Job 提供一个负责解析输出的成员变量。

You could implement something like a JobManager and a Job.

A Job could be a Runnable which has a ProcessBuilder. In it's run method, it starts the process (ProcessBuilder.start), waits for it to exit and calls back to the JobManager when finished, possibly returning the exit status of the process.

The JobManager creates Jobs (each in a new Thread), maintains a collection of current jobs (and maybe a collection of recently finished jobs, maybe a list of failed jobs). Clients can give the JobManager jobs to execute and query for the status (running, finished, failed) of all jobs or a particular job.

Regarding status of the process, the Job could have startTime, endTime and exitStatus variables and associated get methods. You could return these to the client to display a job status table.

Your Job.run method might look something like this.

public void run() {
  startTime = System.currentTimeMillis();  
  process = processBuilder.start();

  // spawn threads to consume process output streams
  // even if you're not going to read them

  while (running) {
    try {
      process.waitFor();
      running = false;
    } catch (InterruptedException e) {
      // you could stop a process by interrupting it's Job thread
      process.destroy();
    }
  }
  exitStatus = process.exitValue();
  endTime = System.currentTimeMillis();
  jobManager.onExit(this);
}

Regarding "% complete", that's only going to be possible if you have some way of measuring it.

If a task should complete within a certain time, you could use that as a rough way of reporting expected completion time / completion percentage.

Or maybe you could capture the output of the processes, using that to set a percentComplete variable in your Job. For example, when you see "message X" in the ouput, set percentComplete=25%. This would mean implementing custom code per type of script - maybe a Job subclass or give the Job a member variable responsible for parsing the output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文