将异步任务的完成/进度监视器与会话关联

时间:2018-03-28 10:37:19

标签: asynchronous java-8 wildfly wildfly-10 stateless-session-bean

我希望能够在java中执行异步任务,并能够保持与用户会话关联的完成(如果可能的话,进展)监视器。这是可能的,如果是的话,这是做什么的?

目前,该任务是作为无状态会话bean方法同步实现的,该方法是从jax-rs端点调用的。

我查看了https://docs.oracle.com/javaee/7/tutorial/ejb-async001.htm,但AsyncResult不可序列化,所以我想我无法将其添加到会话中。

2 个答案:

答案 0 :(得分:3)

使用Spring注释@Async,可以使任何bean /方法异步。 容器将创建一个新线程,并且方法将异步执行。您也可以将会话对象传递给此方法,并在完成后,可以在会话对象中标记属性。 示例: - https://spring.io/guides/gs/async-method/

答案 1 :(得分:0)

JSF示例,适用于Wildfly:

1 in view in view(xhtml)我们有一个上传表格和进度表

<h:form>
    <div align="justify">
    <p:fileUpload style="width: auto" fileUploadListener="#{fileUploadCtrl.handleFileUpload}" mode="advanced" label="Please pick XLS file" update="messages" auto="true" sizeLimit="1000000" allowTypes="/(\.|\/)(xls|xlsx)$/" />
    <p:growl id="messages" showDetail="false" life="4000"/>
    </div>
</h:form>

 <h:form id="wholeform">
    <h:outputText id="statusot" value="#{fileUploadCtrl.message}" />
    <p:spacer width="10" height="10"/>
    <p:poll interval="1" listener="#{fileUploadCtrl.updateStatus}" update="wholeform" />
</h:form>

2在控制器中,它是一个托管bean,我们处理文件,一次是第二次更新状态

@ManagedBean
@ViewScoped

public class FileUploadCtrl {

@EJB
private SomeBusinessLogicClass model;

@EJB
private ProgressTracker progress;

private Future<List<String>> asyncResult;
private int progressId = 0;
private String message;
private boolean busy = false;

public void handleFileUpload(FileUploadEvent event) {

    Set<String> ids = model.populate(event.getFile().getContents());

    progressId = progress.newIndex();
    asyncResult = model.process(ids);
    busy = true;

    FacesMessage message = new FacesMessage("Loaded " + ids.size() + " objects", "");
    FacesContext.getCurrentInstance().addMessage(null, message);
}

public void updateStatus() {

    if (!busy)
        return;

    try {

        if (asyncResult.isDone()) {
            List<String> r = asyncResult.get();
            message = "Job done";
            busy = false;
            progress.delIndex(progressId);
        } else {
            message = progress.getIndex(progressId)+"-th element in work";
        }

    } catch (Exception e) {
        System.out.println("updateStatus " + e.toString());
    }
}

3所有业务逻辑都在EJB中,如SomeBusinessLogicClass或许多其他逻辑。我们还需要一个简单的进度管理器EJB,我完全发布它

@Singleton
public class ProgressTracker {

private Map<Integer,Integer> indexes = new HashMap<>();

public Map<Integer, Integer> getIndexes() {
    return indexes;
}

public void setIndexes(Map<Integer, Integer> indexes) {
    this.indexes = indexes;
}

public Integer newIndex() {
    Integer size = indexes.size();
    indexes.put(size,0);
    return size;
}

public void incIndex(final Integer index) {

    int old = indexes.get(index);
    old++;
    indexes.put(index,old);
}

public Integer getIndex(final Integer index) {
    return indexes.get(index);
}

public void delIndex(Integer index) {
    indexes.remove(index);
}

}

也许这个例子并不优雅,我几乎是前端的新手,但它比没有任何东西更有效。