我有一个带有单个 Notes 文档数据源的 Xpage 页面。
保存文档后,我想(有条件地)触发代理。代理需要一些时间来处理,我们不希望用户必须等待结果,所以它应该异步执行。
我已经设法通过使用 XHR 到代理 URL 来使其从客户端 JS 工作,但我想在服务器端进行,以便更好地控制“下一页”。使用时.run()
或.runonserver()
客户端等待代理完成。
知道如何在没有客户端等待结果的情况下触发 PostSaveDocument 上的代理(来自 SSJS)吗?
我有一个带有单个 Notes 文档数据源的 Xpage 页面。
保存文档后,我想(有条件地)触发代理。代理需要一些时间来处理,我们不希望用户必须等待结果,所以它应该异步执行。
我已经设法通过使用 XHR 到代理 URL 来使其从客户端 JS 工作,但我想在服务器端进行,以便更好地控制“下一页”。使用时.run()
或.runonserver()
客户端等待代理完成。
知道如何在没有客户端等待结果的情况下触发 PostSaveDocument 上的代理(来自 SSJS)吗?
尝试查看 OpenNTF.org 上的 Thread and Jobs 应用程序。在后台运行任务有很好的演示,在这里查看
正如 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 线程的会话 bean(因此它不会被破坏)。或者您可以在代码中发出服务器控制台命令。或者你实现一个 DOTS 监听器。
这可能/可能不是一个选项,具体取决于您的应用程序要求,但我在 onClientLoad 事件中成功调用函数,这基本上在 XPage 完全加载后启动了该过程。