I want to run a group of processes serially. Initially they were set up as page callbacks, but they take too long - at least an hour each. I want to do one thing to trigger all of them to run, but not concurrently, because each takes up too many resources.

So I tried something like this:

background_process_start_locked('dontrunconcurrently', 'mymodule_job1');
background_process_start_locked('dontrunconcurrently', 'mymodule_job2');
background_process_start_locked('dontrunconcurrently', 'mymodule_job3');

but only job 1 ran. I also tried:

background_process_start_locked('dontrunconcurrently1', 'mymodule_job1');
background_process_start_locked('dontrunconcurrently2', 'mymodule_job2');
background_process_start_locked('dontrunconcurrently3', 'mymodule_job3');

and then they all ran simultaneously.

I am putting the above in a page callback to trigger it, so that finishes right away.

What am I missing?

Thanks for any help.

Comments

gielfeldt’s picture

The Background Process API doesn't directly support what you're looking for. However, is sounds as the Drupal Batch API + Background Batch is the thing you are looking for (Background Batch is bundled with Background Process):

<?php
function mymodule_callback() {
  $batch = array(
    'operations' => array(
      array('mymodule_job1', array()),
      array('mymodule_job2', array()),
      array('mymodule_job3', array()),
    ),
    'title' => t('Processing MyModule functions'),
    'init_message' => t('MyModule processing is starting.'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('MyModule processing has encountered an error.'),
  );
  batch_set($batch);

  background_batch_process_batch('admin/config/system/batch/overview');
}
?>

By using the above method, you will also be able to monitor the jobs progress via admin/config/system/batch/overview.

drm’s picture

Status: Active » Closed (works as designed)

Thanks - works great!

BeyersdorferTJ’s picture

background_process_start_locked($handler_name, $function_name); runs a job for this handler_name and than blocks it for the same handler as long as the first one is still running.

So the most easy way would be to run it as a single job just calling your funtions one after the other.

If this is not possible (f.e. if each job takes to much resources) you might want to run it sequencely as you could give the information of all of them to the first job as parameter and when the first one has finished the work it can start the second and so one.