I've been using "notesAgent.runOnServer()" for a long time -- and It ALMOST does what I want. I have always wanted it to detach from the current process so the client doesn't have to sit and wait for it. I wanted to do it without any API calls too. Well, I've done it as of tonight.
You can get much fancier, do error trapping, add prompts and things -- this is the stripped down example.
What happens in the code has two critical parts. First, in the "calling" code, before you actually call the agent you want to run in the background you need to use the "on error resume next" command. When the calling agent drops from connection from the agent it calls, it throws an error state. That command tells the calling agent to ignore that error and not bug the user with it.
Next is the cool part -- as soon as the background agent starts, it issues a Domino server console command to drop the user who started the agent. That will cause the calling agent to drop off the server long enough to terminate its weak link to the agent it called but will not terminate the background agent. Since we've told that calling agent to ignore the error, the user is none the wiser.
There are two big issues to watch out for. First, to issue that command, the user would have to have administrator access. One way around that would be to use yet another agent. A simple agent that ONLY does the lines below that drop a user. Pass that agent a document containing only one field -- the user name to drop. Mark the agent's execution privileges so that it runs on behalf of a user with administration rights. Instead of having your background agent issue the drop command, have the background agent call the drop agent which runs with enough access to do the job. Cool? The other tough thing to do is find a way to stop an agent running on its own out there. The one I'm kicking off could take hours to run and have a real impact on the server in some cases (its multi-threaded). What I did was make a "message queue" view in the database. The background agent marks the document that called it with a uniquely generated "runid", then in the background checks for a message tagged with its current runid in that view from time to time. If it finds one, it checks to see if the waiting message is a request to terminate. I also included a "universal" terminate code in case for some reason the runid becomes unavailable. An action button is used to place a stop message in that queue if need be.
-- Code that starts the background agent --
Dim session as new NotesSession
Dim thisDb as NotesDatabase
Dim agent as NotesAgent
Dim doc as NotesDocument
set thisDb = session.currentDatabase
set doc = session.documentContext
set agent = thisDb.getAgent("Agent I want to run and not wait for")
on error resume next
agent.runOnServer(doc.noteId)
-- And now here's the beginning of the background agent --
Dim s As New notessession
Dim db As notesdatabase
Set db = s.currentdatabase
Call s.SendConsoleCommand(db.Server, |Drop "| & s.UserName & |"|)
Comment Entry |
Please wait while your document is saved.
kludge to get back your client is simply to hit Ctrl-Break once you're sure the
agent has started running on the server. The client stops waiting but it
doesn't stop the on-server agent. You obviously can't kill the process, though,
but in absence of a neat system like yours, it's a real boon for power-user
types :)