在 Grails 应用程序中为长时间运行的作业构建队列的最佳方法是什么?

发布于 2024-07-29 02:20:15 字数 314 浏览 9 评论 0原文

我有一个 Grails 应用程序,它有一些计算密集型优化,运行时间约为 5 分钟(可能更长)。 目前,我正在主请求线程中执行这些操作,即请求返回需要 5 分钟。 它确实有效,但从可用性的角度来看当然很糟糕。

那么以异步方式实现这一点的最佳方法是什么? 我假设必须涉及 ThreadPoolExecutor,但如何启动和访问它? 我可以将其建模为 Grails 服务吗? 或者一份工作(似乎这些只适用于经常性工作)?

另外,处理工作状态的最佳方式是什么? 通过一个标志或者数据库中的一个全新的类? 浏览器是否显示旋转图标并继续轮询直到状态发生变化?

I have a Grails app that has some computationally intensive optimizations with a running time of ~5 minutes (perhaps more). Currently, I'm doing these in the main request thread, i.e. it takes 5 minutes for the request to return. It works, but is of course horrible from a usability perspective.

So what's the best way to implement this in an asynchronous way? I assume a ThreadPoolExecutor would have to be involved, but how do I start and access it? Can I model it as a Grails Service? Or a Job (seems that those are only meant for recurring jobs though)?

Also, what's the best way to handle job status? Via a a flag or perhaps an entire new class in the DB? Have the browser show a spinner and keep polling until the status changes?

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

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

发布评论

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

评论(6

醉生梦死 2024-08-05 02:20:15

有一个 grails 插件 background-thread 可能正是您正在寻找的。

当然,可以推出自己的线程池或使用现有的 Java 东西。

There is a grails plugin background-thread which might be just what you are looking for.

Of course it would be possible to roll your own thread pooling or use existing Java stuff.

残疾 2024-08-05 02:20:15

为此,我将使用 grails JMS 插件

然后,您可以使用“onMessage”方法创建一个服务,该方法自动与底层 jms 提供程序交互(例如 OpenMQ 或 ActiveMQ

它使这种事情变得非常简单。

I'd use the grails JMS Plugin for this.

Then you can create a service with an "onMessage" method that interacts automatically with an underlying jms provider (like OpenMQ or ActiveMQ.

It makes this kind of thing pretty easy.

北音执念 2024-08-05 02:20:15

后台线程插件已经过时,所以我不建议使用它,而且 JMS 对于后台处理来说似乎有点过分了。 JMS 更像是一个消息队列,而不是后台处理实用程序。

我建议使用 Quartz 插件或使用 gpars。

Background-thread plugin is outdated so I wouldn't recommend using it and also the JMS seems overkill for background processing. JMS is more of a message queue rather than background processing utility.

I would recommend either using Quartz plugin or using the gpars.

欢你一世 2024-08-05 02:20:15

本着“可能有效的最简单的事情”的精神,我做了这样的事情作为一项简单的服务。 (当然可能太简单了,欢迎批评)。

我使用了 Groovy 的功能,即 Thread 有一个需要闭包的静态启动方法。 请参阅 http://groovy.codehaus.org/groovy-jdk/java /lang/Thread.html

我在服务上实现了一个方法,如下所示:

synchronized def runThreadedTask() {
  if(taskRunning) { 
    // taskRunning is defined as a service level flag to monitor job status
    // if we are already running the task just return
    return;
  }

  Thread.start {
    taskRunning = true
    // do job processing here
    taskRunning = false
  }
}

In the spirit of the "simplest thing that could possibly work" I have done something like this as a simple service. (Of course it might be too simple, criticism is welcomed).

I used Groovy's feature that Thread has a static start method that takes a closure. See http://groovy.codehaus.org/groovy-jdk/java/lang/Thread.html

I implemented a method on a service that looked like:

synchronized def runThreadedTask() {
  if(taskRunning) { 
    // taskRunning is defined as a service level flag to monitor job status
    // if we are already running the task just return
    return;
  }

  Thread.start {
    taskRunning = true
    // do job processing here
    taskRunning = false
  }
}
昔梦 2024-08-05 02:20:15

grails install-plugin background-thread

def backgroundService

backgroundService.execute("doing my thing", {

// 在这里工作

});

grails install-plugin background-thread

def backgroundService

backgroundService.execute("doing my thing", {

// do work here

});

迷迭香的记忆 2024-08-05 02:20:15

自从有人问这个问题以来已经有一段时间了,但由于它刚刚在搜索中出现,我想我应该补充一点,Thread 对象中现在有一个 Groovy 线程闭包。 你只需使用:

Thread.start {
    // async code goes here
}

然后就到此为止了。 您的异步代码可以在完成后调用更新数据方法或其他方法 - 如果您可以运行多个线程,您可能需要同步它。

It's been a while since this was asked, but since it just came up in a search I figured I'd add that there is now a Groovy threading closure in the Thread object. You just use:

Thread.start {
    // async code goes here
}

and call it a day. Your async code can call an update data method or something when it's done--you might want to synchronize that if you can have multiple threads running.

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