tags:

views:

76

answers:

5

I need to do some additional processing after a Drupal page has been sent.

I know I could fire a background shell command, but I need the current Drupal execution context to be maintained.

I've spent a lot of time looking, but I can't find any documentation in this regard. This is surprising because it must surely be a common requirement.

The only real idea I have is to fire up Drupal (again) via a shell command (exec, etc) and supply it with a pseudo path which would invoke the continued processing. But this seems unnecessarily complex/wasteful.

Any pointers greatly appreciated, tks.

UPDATE: Based on Googletorp and Matt's replies, I just want to point out that I'm not doing housekeeping with this additional processing. Without going into too much detail, I have a number of pages whose content is based on multiple nodes. If one of these child nodes changes then the page needs to be updated immediately, but there is no reason why the user who updated the child node needs to be kept waiting while this happens.

So, the control flow would be:

UPDATE CHILD NODE
RETURN UPDATED CHILD NODE VIEW TO USER (this is where Drupal would normally terminate)
REGENERATE PARENT PAGE
EXIT

Neither Cron nor the rules module have the immediacy I require - but thanks for your input.

A: 

For background processes I recommend a cron, which is built into the drupal API with hook_cron.

Your update indicates you require immediate execution. Therefore you require forking or an asynchronous process. One option is pcntl_fork(), but I've had issues because (with mod_php at least) you don't really want to fork the web server process.

Your best option is probably to set up a page to specifically perform your update, then call it via a forked curl process through popen(). For example,

popen('curl http://localhost/update_parent_nodes &');
Matt S
Thanks Matt, I have updated the question with more detail
David Semeria
Updated my answer based on your updates.
Matt S
Nice update Matt. This is quite similar to how I solved it (see below) with the difference that I went the CLI route rather than creating a new http request. Cheers.
David Semeria
A: 

You can take a look at the rules module, which lets you run code whenever certain events happen.

googletorp
Thanks googletorp, I have updated the question with more detail
David Semeria
A: 

Take a look at hook_exit() - it gets invoked from within drupal_page_footer(), right after the main content has been sent out to the client (which happens indirectly via the page_set_cache() call).

Be aware that it will usually not be invoked for JavaScript/AHAH callbacks, as those terminate the processing themselves earlier on in most cases, but for your described scenario, it should be the right way to go.

Henrik Opel
Thanks Henrik, that looks very promising...
David Semeria
I did some quick tests, and unfortunately the page waits for hook_exit to terminate. Never mind, that would have been almost too easy!
David Semeria
+1  A: 

This is something that you should be doing using http://drupal.org/project/job_queue, and cron to complete whatever you need. However if you want a quick fix and just want the page to appear and things to continue happening you can use the PHP function flush()

http://php.net/manual/en/function.flush.php

openist
Thanks. I've had issues with flush() before so I'd like to avoid that route. Also, I think adding a job to cron and then calling cron immediately seems pretty inelegant. It looks like I'll go with my original idea of launching a background shell script which invokes a new Drupal instance from the command line.
David Semeria
A: 

OP here. Just to share my solution with people for future reference:

I used the second Drupal shell template outlined here

This bootstraps Drupal from the command line. I modified it a bit so I could could specify my own function and args from the CL.

I then invoked the above script using the PHP system() call in conjunction with the background operator (&) - remember to redirect output or the & is irrelevant.

It's a bit messy, but it does exactly what I need.

David Semeria