公开 @Asynchronous 函数的当前进度以在视图中使用
在我的 JEE6-App(在 Glassfish 3.0.1 上运行)中,我有一个 EmailEJB,它必须发送大量邮件。邮件是异步发送的,因此它使用新的 EJB3.1 @Asynchronous 进行注释,让它在单独的线程中运行。现在我希望用户了解该方法的当前状态:已经发送了多少封邮件?
异步发送邮件工作正常,但我不知道如何让外部可以访问进度。看来我这样做的方法是完全错误的,但不知何故它必须是可能的(也许是另一种方法)。这就是我的 EmailEJB 目前的样子(它是一种伪代码,但解释了我想要的内容):
@Stateful
public class EmailEJB {
@Asynchronous
public Future<Integer> sendMails() {
for (int i=0; i<mails.size; i++) {
sendMail(mails[i])
// i want to return the progress without returning ;)
return new AsyncResult<Integer>(i)
}
}
}
//Just for the completeness... from outside, i'm accessing the progress like this:
Future<Integer> progress = emailEJB.sendEmails();
Integer currentvalue = progress.get();
如何在异步函数中返回当前进度,而不用返回取消它?如何向用户显示函数内循环的进度?我需要另一个异步方法吗?有什么提示吗?
In my JEE6-App (running on Glassfish 3.0.1) I have an EmailEJB which has to send lots of mails. The mails are sent asynchronously, so its annotated with the new EJB3.1 @Asynchronous, letting it be run in a separate Thread. Now i want the user to be informed about the current status of the method: How many mails have already been sent?
Sending the mails asynchronously works fine, but i can't figure out how to let the progress be accessible from outside. Seems like my approach to do that is quite wrong, but somehow it has to be possible (maybe another approach). This is how my EmailEJB currently looks like (its kind of pseudo code, but explains what i want):
@Stateful
public class EmailEJB {
@Asynchronous
public Future<Integer> sendMails() {
for (int i=0; i<mails.size; i++) {
sendMail(mails[i])
// i want to return the progress without returning ;)
return new AsyncResult<Integer>(i)
}
}
}
//Just for the completeness... from outside, i'm accessing the progress like this:
Future<Integer> progress = emailEJB.sendEmails();
Integer currentvalue = progress.get();
How can i return the current progress inside my asynchronous function, without cancelling it with a return? How can i show the user the progress of a loop inside a function? Do i need another asynchronous method? Any hints?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有人吗?好的,这是我的解决方案。我不确定这是否是一个很大的解决方法,或者只是完成此任务的一种方法。
由于 @Asynchronous 方法无法访问 Session 上下文,因此也没有 Session Bean(至少我不知道如何,我总是遇到 ConcurrentModificationErrors 或类似的错误),我创建了一个 Singleton ProgressEJB,其中包含一个 HashMap:
此 hashmap 应该映射 SessionId (字符串)到整数值(进度 0->100)。因此,用户会话与进度相关联。
在我的 EmailEJB 中,我注入了这个 ProgressEJB,并且在我的 @Asynchronous 方法中,每次发送电子邮件时我都会增加该值:
sessionId 来自我的托管(焊接)Bean,在调用该函数时:
现在我可以使用 Ajax 轮询从我的 JSF 视图中访问 EmailManager 的进度,告诉用户已经发送了多少邮件。刚刚与 2 个用户进行了测试,似乎有效。
Nobody? Ok so this is my solution. Im not sure if this is a big fat workaround or just a way to get this done.
Since an @Asynchronous method cannot access the Session context, and therefore also no Session Beans (at least i dont know how, i always got ConcurrentModificationErrors or similar ones) i created a Singleton ProgressEJB, which contains a HashMap:
This hashmap should map the SessionId (a String) to an Integer value (the progress 0->100). So a user session is associated with a progress.
In my EmailEJB, i'm injecting this ProgressEJB, and in my @Asynchronous method, i'm increasing the value everytime an email has been sent:
The sessionId comes from my Managed (Weld) Bean, when calling the function:
Now i can access progress from EmailManager from my JSF view with Ajax Polling, telling the user how many mails already have been sent. Just tested it with 2 users, seems to work.
我在这里也只看到一个@Singleton 解决方案。
但这意味着需要 Housekeeping in ProgressEJB。例如,需要付出一些努力来从哈希图中删除旧会话。
I also see only a @Singleton solution here.
But this imply the need of Housekeeping in ProgressEJB. E.g. some effort is needed to prune old session from Hashmap.
另一种解决方案描述于
有什么方法可以知道EJB 异步进程的进度?
此解决方案不需要 Stateful Bean。
保存进度的 Context-Object。
使用方法非常简单。
Another solution is described in
Is there any way to know the progress of a EJB Asynchronous process?
This solution does not need a Stateful Bean.
The Context-Object, which holds the progress.
The usage is very easy.