公开@Asynchronous函数的当前进度以在View中使用 [英] Expose current progress of an @Asynchronous function to use in View

查看:154
本文介绍了公开@Asynchronous函数的当前进度以在View中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的JEE6-App(在Glassfish 3.0.1上运行)中,我有一个EmailEJB,它必须发送大量邮件。邮件是异步发送的,所以它用新的EJB3.1 @Asynchronous注释,让它在一个单独的Thread中运行。现在我想让用户了解该方法的当前状态:已经发送了多少封邮件?

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?

异步发送邮件工作正常,但我可以'弄清楚如何从外部获取进展。似乎我的做法是非常错误的,但不知何故它必须是可能的(也许是另一种方法)。这就是我的EmailEJB目前的样子(它的伪代码,但解释了我想要的):

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?

推荐答案

没有人?好的,这是我的解决方案。我不确定这是一个很大的解决方法,还是只是一种完成这项工作的方法。

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.

由于@Asynchronous方法无法访问Session上下文,因此也没有会话Bean(至少我不知道如何,我总是得到ConcurrentModificationErrors或类似的)我创建了一个Singleton ProgressEJB,它包含一个HashMap:

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:

@Singleton @LocalBean @Startup
public class ProgressEJB {
  private HashMap<String, Integer> progressMap = new HashMap<String, Integer>
  // getters and setters
}

此hashmap应映射SessionId(字符串)到整数值(进度0-> 100)。因此,用户会话与进度相关联。
在我的EmailEJB中,我正在注入此ProgressEJB,并且在我的@Asynchronous方法中,每次发送电子邮件时我都会增加值:

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:

@Stateful @LocalBean
public class EmailEJB {
@Inject
private ProgressEJB progress;
// Mail-Settings
...
@Asynchronous
public void sendEmails(user:User, message:Message, sessionId:String) {
  progress.progressMap.put(sessionId, 0);
  for (int i=0; i<mails.size; i++) {
    sendMail(mails[i])
    progress.getProgressMap().put(sessionId, (i / mails.size) * 100)
  }
  progress.getProgressMap().remove(sessionId);
}

在调用函数时,sessionId来自我的Managed(Weld)Bean:

The sessionId comes from my Managed (Weld) Bean, when calling the function:

@SessionScoped
@Named
public class EmailManager {
  @Inject 
  private ProgressEJB progress;
  @Inject
  private FacesContext facesContext;

  private String sessionId;

  @PostConstruct
  private void setSessionId() {
    this.sessionId = ((HttpSession)facesContext.getExternalContext().getSession(false)).getId();
  }

  public Integer getProgress() {
    if (progress.getProgressMap().get(sessionId) == null)
      return 100;
    else 
      return progress.getProgressMap().get(sessionId);
  }
}

现在我可以从我的JSF视图中访问EmailManager的进度使用Ajax Polling,告诉用户已经发送了多少封邮件。刚刚用2个用户进行测试,似乎有效。

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.

这篇关于公开@Asynchronous函数的当前进度以在View中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆