PostSaveDocument извикване на агент асинхронно

Имам Xpage страница с един източник на данни за документ на Notes.

След като запазя документ, искам (условно) да активирам агент. Агентът отнема известно време за обработка и ние не искаме потребителят да чака резултата, така че трябва да се изпълнява асинхронно.

Успях да го накарам да работи от JS от страна на клиента, като използвах XHR към URL адреса на агента, но бих искал да го направя от страна на сървъра, за да мога да контролирам по-добре „Следващата страница“. Когато използвате .run() или .runonserver(), клиентът изчаква, докато агентът завърши.

Някаква идея как мога да задействам агент (от SSJS) на PostSaveDocument, без клиентът да чака резултата?


person BvG013    schedule 04.06.2012    source източник


Отговори (4)


Опитайте да разгледате приложението Thread and Jobs на OpenNTF.org. Има хубави демонстрации на изпълнение на задача във фонов режим, проверете тук

person Martin Jinoch    schedule 12.06.2012
comment
Използвах кода на JobScheduler и го промених, за да отговаря на нуждите ми. Изглежда, че работи. - person BvG013; 20.06.2012

Както предложи Мартин, използвах примера на JobScheduler на OpenNtf и го модифицирах, за да отговаря на моите нужди. Полученият код може да бъде намерен по-долу. Всякакви коментари или подобрения са добре дошли.

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;
        }
    }
};
}
person BvG013    schedule 20.06.2012
comment
Как наричате класа? В сесиен боб? - person stwissel; 26.06.2012
comment
Извиквам го от SSJS функция, използвайки importPackage. - person BvG013; 23.07.2012

Можете да използвате сесиен bean (за да не бъде унищожен), който стартира Java нишка. Или можете да подадете в код команда на сървърната конзола. Или прилагате DOTS слушател.

person stwissel    schedule 04.06.2012
comment
Благодаря ви за отговора. Ще разгледа допълнително вариант 1 и 3. - person BvG013; 04.06.2012
comment
Или обикновен стар агент, задействан при промяна на документи. - person D.Bugger; 06.06.2012

Това може/може да не е опция в зависимост от изискванията на вашето приложение, но имам добър успех при извикване на функцията в събитието onClientLoad, което по същество стартира процеса, след като XPage се зареди напълно.

person Russell Maher    schedule 07.06.2012