Xpages PostSaveDocument异步调用代理

Xpages PostSaveDocument异步调用代理,xpages,asynchronous,xpages-ssjs,Xpages,Asynchronous,Xpages Ssjs,我有一个带有单个Notes文档数据源的Xpage页面 保存文档后,我希望(有条件地)触发代理。代理需要一些时间来处理,我们不希望用户必须等待结果,因此它应该异步执行 我已经通过使用代理URL的XHR从客户端JS成功地使其工作,但我希望在服务器端这样做,以便更好地控制“下一页”。使用.run()或.runonserver()时,客户端将等待代理完成 你知道如何在客户端不等待结果的情况下触发PostSaveDocument上的代理(来自SSJS)吗?你可以使用会话bean(这样它就不会被破坏)启动J

我有一个带有单个Notes文档数据源的Xpage页面

保存文档后,我希望(有条件地)触发代理。代理需要一些时间来处理,我们不希望用户必须等待结果,因此它应该异步执行

我已经通过使用代理URL的XHR从客户端JS成功地使其工作,但我希望在服务器端这样做,以便更好地控制“下一页”。使用
.run()
.runonserver()
时,客户端将等待代理完成


你知道如何在客户端不等待结果的情况下触发PostSaveDocument上的代理(来自SSJS)吗?

你可以使用会话bean(这样它就不会被破坏)启动Java线程。或者您可以在代码中发出服务器控制台命令。或者您实现了一个DOTS侦听器。

这可能是一个选项,也可能不是,这取决于您的应用程序需求,但我在OnClient Load事件中调用函数取得了很好的成功,这实际上是在XPage完全加载后启动进程。

尝试查看OpenNTF.org上的线程和作业应用程序。有很多在后台运行任务的演示,检查一下,正如Martin建议的那样,我在OpenNtf上使用了JobScheduler示例,并对其进行了修改以满足我的需要。产生的代码可以在下面找到。欢迎提出任何意见或改进

import java.security.AccessController;
import java.security.PrivilegedAction;

import lotus.domino.Agent;
import lotus.domino.Database;

import lotus.domino.NotesException;
import lotus.domino.Session;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;

import com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor;

public class JobRunner {

public static void start(String dbPath, String agentName, String paramDocId) {

    synchronized (JobRunner.class) {

        runningJob = new ISPJob(dbPath, agentName, paramDocId);
        runningJob.addJobChangeListener(new JobChangeAdapter() {
            public void done(IJobChangeEvent event) {
                System.out.println("Done event");
                runningJob = null;
            }
        });
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                runningJob.schedule();
                return null;
            }
        });

    }
}

private static ISPJob runningJob;

private static final class ISPJob extends Job {

    private ThreadSessionExecutor<IStatus> executor;

    private String docId;
    private String dbPath;
    private String agentName;

    public ISPJob(String paramDbPath, String paramAgentName, String paramDocId) {
        super(paramDocId);

        this.docId = paramDocId;
        this.dbPath = paramDbPath;
        this.agentName = paramAgentName;

        this.executor = new ThreadSessionExecutor<IStatus>() {
            @Override
            protected IStatus run(Session session) throws NotesException {

                System.out.println("Job started" + docId);
                System.out.println("   >> Session created: "
                        + session.getUserName() + ", Effective User:"
                        + session.getEffectiveUserName());

                    Database db = session.getDatabase(null,dbPath);

                    if (db != null) {
                        try {
                            if (!db.isOpen()) db.open();
                            if (db.isOpen()) {
                                System.out.println("   >> Database opened: "
                                        + db.getTitle());
                                Agent agent = db.getAgent(agentName);
                                try {
                                    System.out.println("   >> Agent Started: " + agent.getName());
                                    agent.run(docId);
                                    System.out.println("   >> Agent Ran: " + agent.getName());
                                } finally {
                                    agent.recycle();
                                }

                            }
                        } finally {
                            db.recycle();                           
                        }

                }
                System.out.println("Job completed");

                return Status.OK_STATUS;
            }
        };

    }

    protected IStatus run(IProgressMonitor monitor) {
        try {
            return executor.run();
        } catch (Exception ex) {
            return Status.CANCEL_STATUS;
        }
    }
};
}
导入java.security.AccessController;
导入java.security.PrivilegedAction;
导入lotus.domino.Agent;
导入lotus.domino.Database;
导入lotus.domino.NotesException;
导入lotus.domino.Session;
导入org.eclipse.core.runtime.IProgressMonitor;
导入org.eclipse.core.runtime.IStatus;
导入org.eclipse.core.runtime.Status;
导入org.eclipse.core.runtime.jobs.IJobChangeEvent;
导入org.eclipse.core.runtime.jobs.Job;
导入org.eclipse.core.runtime.jobs.JobChangeAdapter;
导入com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor;
公职人员{
publicstaticvoidstart(stringdbpath、stringagentname、stringparamdocid){
已同步(JobRunner.class){
runningJob=新的ISPJob(dbPath、agentName、paramDocId);
runningJob.addJobChangeListener(新的JobChangeAdapter(){
公共作废完成(IJobChangeEvent事件){
System.out.println(“完成事件”);
runningJob=null;
}
});
AccessController.doPrivileged(新的PrivilegedAction(){
公共对象运行(){
runningJob.schedule();
返回null;
}
});
}
}
私有静态ISPJob运行job;
私有静态最终类ISPJob扩展作业{
私有线程SessionExecutor执行器;
私有字符串docId;
私有字符串路径;
私有字符串代理名;
公共ISPJob(字符串paramDbPath、字符串paramAgentName、字符串paramDocId){
super(paramDocId);
this.docId=paramDocId;
this.dbPath=paramDbPath;
this.agentName=paramAgentName;
this.executor=新线程SessionExecutor(){
@凌驾
受保护的IStatus运行(会话)引发NotesException{
System.out.println(“作业已启动”+docId);
System.out.println(“>>创建的会话:”
+session.getUserName()+,有效用户:
+session.getEffectiveUserName());
Database db=session.getDatabase(null,dbPath);
如果(db!=null){
试一试{
如果(!db.isOpen())db.open();
if(db.isOpen()){
System.out.println(“>>数据库已打开:”
+db.getTitle());
Agent=db.getAgent(agentName);
试一试{
System.out.println(“>>代理已启动:“+Agent.getName());
agent.run(docId);
System.out.println(“>>代理运行:“+Agent.getName());
}最后{
agent.recycle();
}
}
}最后{
db.recycle();
}
}
System.out.println(“作业完成”);
返回状态。OK_状态;
}
};
}
受保护的IStatus运行(IProgressMonitor监视器){
试一试{
返回executor.run();
}捕获(例外情况除外){
返回状态。取消状态;
}
}
};
}

感谢您的回复。将进一步研究选项1和3。或者一个普通的旧代理在“文档被修改时”触发。我使用了JobScheduler代码,并对其进行了更改以满足我的需要。看起来不错。你怎么称呼这个班?在会话bean中?我使用importPackage从SSJS函数调用它。