سؤال

I have an Xpage page with a single Notes document datasource.

After saving a document I want to (conditionally) trigger an agent. The agent takes some time to process and we don't want the user to have to wait for the result, so it should be executed asynchronously.

I've managed to get it working from client side JS by using an XHR to the agent URL, but I would like to do it server side so I can control the "Next page" better. When using .run() or .runonserver() the client waits till the agent completes.

Any idea how I could trigger an agent (from SSJS) on PostSaveDocument without the client waiting for the result?

هل كانت مفيدة؟

المحلول 2

As Martin suggested I used the JobScheduler example on OpenNtf and modified it to suit my needs. Resulting code can be found below. Any comments or improvements are welcome.

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;
        }
    }
};
}

نصائح أخرى

Try to look at Thread and Jobs application on OpenNTF.org. There are nice demos of running task in background, check it here

You could use a session bean (so it won't get destroyed) that kicks off an Java thread. Or you could issue in code a server console command. Or you implement a DOTS listener.

This may/may not be an option depending on your application requirements but I am having good success calling function in the onClientLoad event which essentially kicks off the process after the XPage has fully loaded.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top