wp-background-processing icon indicating copy to clipboard operation
wp-background-processing copied to clipboard

Tutorial - How to get it working

Open Luc45 opened this issue 6 years ago • 3 comments

Hey,

First of all I would like to thank the creators of this library. It is simply awesome!

However, it might be really tricky to get this up and running.

I would like to provide a detailed breakdown of common issues I faced implementing this and how to solve them.

The first thing to understand about this package is that it only consists of TWO files:

  • wp-async-request.php
  • wp-background-process.php (extends wp-async-request.php)

The first one is used to dispatch a single async request. The second one is a powerful batch processor of long-running tasks.

That said, you can either install this library as a plugin by cloning the repository and installing it as a plugin, or you can just add these two files to your project. I recommend the second approach, as you will have more control on when the classes will be available for you to use.

If you install it as a plugin, you have to be careful, because your async class will have to be hooked at plugins_loaded, and the class that calls your async class will have to load after that.

Minimal example with plugin:

<?php
/**
* Plugin name: Async Test with wp-brackground-processing as a plugin
*/

// We hook this at plugins_loaded, since WP_Background_Process is in wp-background-process.php
add_action('plugins_loaded', function() {
class BackgroundAsync extends WP_Background_Process
    {
        protected $action = 'just_testing';
        protected function task( $item ) {
            sleep(1);
            error_log($item);
            return false;
        }
    }
});

class BackgroundTest
{
    public function __construct() {
        $this->task = new BackgroundAsync;
        if (isset($_GET['async_test'])) {
            $names = ['name1', 'name2', 'name3', 'name4'];

            foreach ( $names as $name ) {
                $this->task->push_to_queue( $name );
            }

            $this->task->save()->dispatch();
        }
    }
}

// We hook this at plugins_loaded with priority 11, so that BackgroundAsync will already be loaded then.
add_action('plugins_loaded', function() {
    new BackgroundTest();
}, 11);

If you load the classes in your project, it gets easier:

<?php
require_once __DIR__ . '/wp-async-request.php';
require_once __DIR__ . '/wp-background-process.php';

class BackgroundAsync extends WP_Background_Process
{
    protected $action = 'just_testing';
    protected function task( $item ) {
        sleep(1);
        error_log($item);
        return false;
    }
}

class BackgroundTest
{
    public function __construct() {
        $this->task = new BackgroundAsync;
        if (isset($_GET['async_test'])) {
            $names = ['name1', 'name2', 'name3', 'name4'];

            foreach ( $names as $name ) {
                $this->task->push_to_queue( $name );
            }

            $this->task->save()->dispatch();
        }
    }
}
// Now we just need plugins_loaded here, because otherwise it throws a "Call to undefined function wp_create_nonce()"
add_action('plugins_loaded', function() {
    new BackgroundTest();
});

This should get you up and running for most cases. Just remember that BackgroundAsync class must be called somewhere during the execution of your script, because it is the instantiation of the class that registers the callback to the cron!! That's probably why a lot of people can't get this to work.

That means, you can then use something like:

// Somewhere in the execution of your plugin
add_action('plugins_loaded', function() {
    $backgroundAsync = new BackgroundAsync();
    $background = new BackgroundTest($backgroundAsync);
    $background->doSomethingThatWillPushToQueueThenSaveAndDispatch();
});

// BackgroundAsync.php
class BackgroundAsync { ... }

// BackgroundTest.php
class BackgroundTest {
    protected $async;
    public function __construct(BackgroundAsync $async) {
        $this->async = $async;
    }
    // ...
}

Other tips:

wp-cli is your friend debugging crons.

Example: wp cron event list wp cron event run wp_some_cron_event

That's it, I hope this tutorial helps people get up and running with this awesome library!

Luc45 avatar Feb 01 '19 07:02 Luc45

Hi Luc,

I'm trying to run the second example. The one where you use

require_once __DIR__ . '/wp-async-request.php';
require_once __DIR__ . '/wp-background-process.php';

.

When I debug the plugin, the function isset($_GET['async_test']) in class BackgroundTest does not evaluate to true. Do you have any hints what I can do about that?

Best, Michael

michaelhochleitner avatar Jun 13 '19 08:06 michaelhochleitner

Thanks, Luc! That was a great help. I was stuck not being able to get cron working and then remembered that I moved the instantiation line out of the init / plugins_loaded context. And I had the demo plugin installed parallel to the project I was using it in... had to deactivate it. Thanks!

devwax avatar Sep 12 '19 04:09 devwax

Thank you!!!!!

zeshanshani avatar Sep 17 '20 17:09 zeshanshani

I'm going to close this issue as a tutorial doesn't really fit here.

However, it's much appreciated, and if someone felt there were some improvements that could be made to the README.md via a PR that does not bloat it, or better still, maybe add a new docs section to the repo with quick start guide to kick it off, I'm sure it'd be welcomed!

ianmjones avatar Apr 11 '23 19:04 ianmjones