在 Grails 应用程序中为长时间运行的作业构建队列的最佳方法是什么?
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
有一个 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.
为此,我将使用 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.
后台线程插件已经过时,所以我不建议使用它,而且 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.
本着“可能有效的最简单的事情”的精神,我做了这样的事情作为一项简单的服务。 (当然可能太简单了,欢迎批评)。
我使用了 Groovy 的功能,即 Thread 有一个需要闭包的静态启动方法。 请参阅 http://groovy.codehaus.org/groovy-jdk/java /lang/Thread.html
我在服务上实现了一个方法,如下所示:
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:
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
});
自从有人问这个问题以来已经有一段时间了,但由于它刚刚在搜索中出现,我想我应该补充一点,Thread 对象中现在有一个 Groovy 线程闭包。 你只需使用:
然后就到此为止了。 您的异步代码可以在完成后调用更新数据方法或其他方法 - 如果您可以运行多个线程,您可能需要同步它。
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:
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.