My module does some tasks via Batch API. To avoid duplicating code, I want to do those same tasks during a cron run by programmatically starting and executing the batch without trying to redirect the user to the standard batch job progress bar thingie. There seems to be the facility for this by setting the 'progressive' value of the $process_info array to FALSE, but by the same token, there doesn't seem to be a way to do that - it's hard-coded to TRUE . From D6's form.inc (D7's version is the same in this regard):

function batch_process($redirect = NULL, $url = NULL) {
  $batch =& batch_get();

  if (isset($batch)) {
    // Add process information
    $url = isset($url) ? $url : 'batch';
    $process_info = array(
      'current_set' => 0,
      'progressive' => TRUE, // <= HERE
      'url' => isset($url) ? $url : 'batch',
      'source_page' => $_GET['q'],
      'redirect' => $redirect,
    );
    $batch += $process_info;

    if ($batch['progressive']) {
      // Clear the way for the drupal_goto redirection to the batch processing
      // page, by saving and unsetting the 'destination' if any, on both places
      // drupal_goto looks for it.
      // […snip…]
      drupal_goto($batch['url'], 'op=start&id='. $batch['id']);
    }
    else {
      // Non-progressive execution: bypass the whole progressbar workflow
      // and execute the batch in one pass.
      require_once './includes/batch.inc';
      _batch_process();
    }
  }
}

Unless I'm missing something, this means that, though the functionality exists to do what I want to do, it's not actually possible to do so without hacking core - the code in that "else" branch will never, ever execute. One dead kitten later, I get the expected result.

However, I will allow that I'm just misunderstanding how to use an esoteric feature of this esoteric API and that doing what I need to do is possible without slaughtering kittens; in which case, a bit of edumacation would be appreciated.

Issue fork drupal-638712

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

Yes, it's an API overlook :-(.

You can do that with:

$batch =& batch_get();
$batch['progressive'] = FALSE;

before calling batch_process().

Garrett Albright’s picture

Title: Non-progressive batch operations not possible? » Non-progressive batch operations not possible
Category: support » bug
Status: Active » Needs review
FileSize
3.31 KB
462 bytes
1.51 KB
3.97 KB

That works. Thank you. (Is there any documentation somewhere on that =& operator? I think I get what it does by peeking at the code, but I'd like to see it written down somewhere. Unfortunately, it's impossible to search for "=&" in Yahoo, Google or PHP.net's built-in search engine, and a quick glance of the "Operators" section of the PHP.net docs wasn't profitable.)

So how can we fix this? Perhaps add a new ['progressive'] key to the array passed to batch_set() which gets passed along to the $batch['progressive'] value in batch_process()… ugh. If any of the sets have a FALSE ['progressive'] key, the batch won't be run as progressive…? The attached patch should implement that, as well as cleaning up the docs in the D6 version and removing mention of a fictitious batch_init() from both versions. If this counts as an API change and is therefore unable to be committed, please at least commit the documentation correction patches.

yched’s picture

Version: 6.x-dev » 7.x-dev

That would rather be a parameter for batch_process(), IMO.

Doc cleanup patches are good to go. Oops for batch_init(), that function was refactored out even before Batch API landed in D6...
Could you post the isolated patch for D7 ?

Garrett Albright’s picture

Could you post the isolated patch for D7 ?

What do you mean by "isolated?" Do you mean just the progressive tweak without the batch_init() removal from the comments? If so, here you go.

It being a parameter for batch_process() makes sense too, but the D6 version already has two parameters, and the D7 version has three…

yched’s picture

Sorry, I meant just batch_api_docs_cleanup-D7.patch so we can set this to RTBC and backport asap.

The 'progressive' thing still needs some thinking IMO, + I'd prefer to wait for #629794: Scaling issues with batch API to land ;-)

Dave Reid’s picture

Status: Needs review » Reviewed & tested by the community

Wow just ran into this trying to run a batch process from drush, which is impossible without this bug/hack. Patch in #4 worked for me.

Dave Reid’s picture

Issue tags: +Needs backport to D6

This will need a backport to D6 as well.

yched’s picture

Issue tags: -Needs backport to D6

Plz see my #3 / #5

Dries’s picture

Is there any down-sides to setting this parameter? The documentation makes it read as if it is a UI-thing only.

Dave Reid’s picture

Not that I can tell. Being able to set a batch as not progressive allows us to run it in the command line and Drush.

Garrett Albright’s picture

…and during a cron run, which was my goal. Not that that is necessarily the right answer to my problem, but it works.

yched’s picture

re Dries #9

Is there any down-sides to setting this parameter? The documentation makes it read as if it is a UI-thing only.

Batch "API" is mainly two functions:
- batch_set(): define a set of batched operations to be run by the batch engine. Several independent code branches can their own add batched ops (for instance several form submit handlers defined in different modules).
- batch_process(): launch the execution of the batch sets that were defined earlier during the page request. Batch sets are executed sequentially and stay independent the whole time.

Saying whether processing should happen through the progressbar UI or some other iteration mechanism or just 'in one pass' is something for batch_process()
- it will affect the whole processing, so what if set A specifies 'progressive' and batch B specifies 'non progressive' ?
- it's the caller of batch_process() who knows its own context (form submission, page callback -> UI OK, programmatic form, cron, drush -> UI not OK) and therefore has the elements to decide if execution should be progressive or not. In the generic case, callers of batch_set() have no clue, an it should not matter to them anyway.
- for this exact reason, it's batch_process() that received the option to specify a custom 'iterator' ($redirect_callback) in #555762: Changes to batch API

Adding the 'progressive' option on batch_set() as the patch does is conceptually wrong, it's only 'easier' in terms of API changes (because it adds an optional property inside the $batch_set array param)

I'd much rather have us add the option on batch_process(). 2 options:
1 - light change: 4th optional parameter for batch_process() - no API break
2 - clean and future proof change: rework the current arguments of batch_process() into a single $options array. Note that most batches in contrib are set in form submits, and so should not be affected by the change since i this case Form API takes care of the batch_process() call.

Of course I strongly favor the latter, but that would need a green light for the API break.

Garrett Albright’s picture

Status: Reviewed & tested by the community » Needs work

Okay, I think Dave and I interpreted the question differently than yched, but I have to say I agree with yched's post conceptually - doing it via batch_process() would probably be smartest. However, my interpretation of the code already in place was that it was intended that that would be something set with batch_set(), so that's the path I took with my patch.

I say we make a patch which satisfies option 1 for now. In the chance we get the green light to break API, we can adapt it to option 2 - and then pile on patches to unbreak update.php and such. This isn't something I can tackle at the moment; yched, Dave, could either of you take this on?

yched’s picture

Status: Needs review » Needs work

Attached patch does the lightest approach (#12 option 1). API addition, no API break. Hackish, though[edit: hackish is not the word, let's say that's a kind of a param soup]

I think the clean version is something like: batch_process($options)
Supported options:
- iteration_callback (current $redirect_callback param): the iteration method. Defaults to 'drupal_goto', FALSE means not progressive.
- process_url (current $url param): page that holds the progress bar. Defaults to '\batch'. Only used if 'iteration_callback' == 'drupal_goto'.
- redirect_url (current $redirect param): page to redirect after processing. Defaults to the 'redirect' property of the last processed set. Only used if 'iteration_callback' == 'drupal_goto'.

I can try to work on that approach if the API change is validated.
Meanwhile, CNR for the 'code-freeze friendly' patch.

yched’s picture

Status: Needs work » Needs review
FileSize
2.79 KB

er, patch.

moshe weitzman’s picture

Status: Needs work » Needs review

subscribe since drush updatedb will need changes when this lands.

Status: Needs review » Needs work

The last submitted patch failed testing.

Status: Needs work » Needs review

Re-test of batch_progressive-638712-13.patch from comment #15 was requested by nonsie.

nonsie’s picture

Subscribe

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

small, helpful patch.

Dave Reid’s picture

Still not the easiest to call batch_process() if you want a non-progressive run. The first three settings don't matter if the fourth is FALSE. Would it be too much to ask if we move the progressive parameter first?

Garrett Albright’s picture

I would imagine that would break everything which currently uses Batch API. At that point, we might as well get rid of the mile-long list of parameters approach and go with the parameters-in-an-array approach, 'cuz that's going to break everything too.

webchick’s picture

Checking to see if this still applies now that the scalable batch API patch landed.

Status: Reviewed & tested by the community » Needs review

Re-test of batch_progressive-638712-13.patch from comment #15 was requested by webchick.

Status: Needs review » Needs work

The last submitted patch, batch_progressive-638712-13.patch, failed testing.

aspilicious’s picture

Status: Needs work » Needs review
FileSize
2.64 KB

I am trying to reroll this...

1) tried to apply on latest head, check
2) tried to install with changes check

So all this needs is a proper review if the bot is happy

q0rban’s picture

Subscribe

retester2010’s picture

#26: batch-progressive-638712-26.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, batch-progressive-638712-26.patch, failed testing.

Dave Reid’s picture

Status: Needs work » Needs review
FileSize
3.08 KB

Let's try this instead. Let's make it a non-progressive batch if the $redirect_callback parameter is FALSE.

bleen’s picture

subscribing

btopro’s picture

sub... kind of a major issue for trying to reuse batch processes as background jobs on server..

markj’s picture

Subscribing.... Dave's patch passed tests 3.5 years ago.

RoSk0’s picture

Component: forms system » batch system
Issue summary: View changes
FileSize
2.79 KB

Reroll

RoSk0’s picture

texas-bronius’s picture

Seems to work for me:

require_once DRUPAL_ROOT . '/includes/batch.inc';
  $batch = array(
    'title' => 'Test of Batch in WebTestCase',
    'operations' => array(
      array('iht_custom_test_of_batching_process', array()),
    ),
    'finished' => 'iht_custom_test_of_batching_finished',
  );
  batch_set($batch);
  batch_process(NULL, NULL, FALSE);
}

I'd really been poking at this from every other conceivable angle -- so glad to have come across this thread. I think I understand why we are putting the burden of determining progressive mode on batch_process() and not a param 'progressive' => FALSE on $batch on batch_set($batch). So what seems to be working (with this third-parameter-truthiness patch) for me is:

...
  batch_set($batch);
  if (php_sapi_name() == 'cli') {
    // Process non-progressive batch (launched from command line)
    batch_process(NULL, NULL, FALSE);
  } else {
    // Process progressive batch (in browser)
    batch_process('');
  }

See PHP docs for php_sapi_name().

jouri’s picture

In Drupal 8 it's not possible to do a non progressive batch through cli because there's always a route match needed.
I fixed this in the attached patch.

Status: Needs review » Needs work

The last submitted patch, 37: core-batch-638712-37.patch, failed testing.

jouri’s picture

FileSize
1.42 KB

Forgot the html subfolder, removed it.

Cameron Tod’s picture

Version: 7.x-dev » 8.0.x-dev
Status: Needs work » Needs review
FileSize
1.42 KB

Latest patch is against 8.0.x - bumping version though I'm not sure on which branch this should go in.

Have rerolled patch to remove preceding 'html' directory.

Cameron Tod’s picture

Updated the comment and param name, I think this construction is a bit more readable. Re #36, It does feel a bit weird to be disabling progressive batching via setting the source_url rather than setting $batch['progressive'] directly.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jonathanshaw’s picture

Title: Non-progressive batch operations not possible » Make non-progressive batch operations possible
Version: 8.1.x-dev » 8.3.x-dev
Category: Bug report » Feature request
Issue tags: +Needs tests

Looks like a feature request rather than an outright bug?

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Tim Bozeman’s picture

Category: Feature request » Bug report
FileSize
6.5 KB

Old issue, but it seems to have resurfaced.

Progressive = TRUE is hard coded in form.inc batch_process(). Here's a fresh patch. It's only a minor tweak, but the indentation is different so it changed a bunch of lines...

With the patch, you can run a cron or cli batch job like this:

batch_set([
  'title' => t('Exporting'),
  'operations' => [
    [
      'my_function_1',
      [
        $account
          ->id(),
        'story',
      ],
    ],
    [
      'my_function_2',
      [],
    ],
  ],
  'finished' => 'my_finished_callback',
  'file' => 'path_to_file_containing_myfunctions',
]);
$batch =& batch_get();
$batch['progressive'] = FALSE;

batch_process();
borisson_’s picture

Status: Needs review » Needs work

I like that this makes the code little less indented and adds early returns.

I don't like that this uses $_SESSION instead of the symfony's session storage.

In any case, we need to add a test that fails without this patch attached.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

whereisaaron’s picture

Glad I ran into this thread for the required hack.

But 10 years and multiple passing patches and simple as three line to add the missing option, but still nothing applied to fixed this hard-coding bug, not to D6 or D7 or D8?

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

handkerchief’s picture

Any news on that?

borisson_’s picture

I'm pretty sure we need to add tests to this and we can get this in after that. Asking for someone else to do that will not make that go quicker.

I'm also not sure about the last patch (#47) over #41. It is 5 times as big and does a lot of unrelated work. I really like that direction because it makes the code better but it is harder to see what really needed to change. We can do the refactor in a followup instead.

So if #41 still applies (and fixes the issue) - I think that is a good place to start, all we would need added on top of that is the test :)

batkor’s picture

subscribe

handkerchief’s picture

Ok #1 was my solution. Simple.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

satbir.singh made their first commit to this issue’s fork.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.