If you are looking to run a Task T which cannot be split in to units, then you can stop reading right here. The ability to run long running task until it completes is restricted by hosting provider. But in this article I will show you how to process large number of items by creating a action scheduler queue.
What action scheduler allows us to do?
By default it doesn't implement any queuing system to run a long list of operations. The two methods available are
- Create a single action A which will run on future
- Create a repeating action R which will be called continuously.
We need to design the queue considering these constraints.Lets say i have 1000 posts to be processed, i can process 5 posts without timeout everytime, then we have to enqueue 1000 / 5 = 200 actions in action scheduler.
The process of enqueuing actions can also timeout the php runner which was the initial problem we wanted to overcome.
My solution is to simply enqueue the actions one by one inside the handler method. Lets say i have actions A1 ( offset = 0, limit = 5) , A2 ( offset = 5, limit = 5). I am not going to enqueue A2, i will enqueue it once the A1 completes.
Enough Theory, Show Me The Code!
<?php
function start() {
// Note that we add only A1 here.
as_enqueue_async_action( 'my_hook', array( 'offset' => 0, 'limit' => 5, 'count' => 1000 ), 'my-group');
}
add_action('my_hook', function ( $args ) {
// do_some_action($args);
// Lets assume we did some work with $args. Now update the offset.
$args['offset'] = $args['offset'] + $args['limit'];
if ( $args['count'] < $args['offset']) {
// process is complete, return early.
return;
}
// we still need to run the process, enqueue another action.
as_enqueue_async_action( 'my_hook', $args );
});
with this simple trick you process a large list of items without worrying about timeout. The only disadvantage of enqueuing next action on the executed action is that we can't leverage the concurrency provided by action scheduler.
0 comments:
Post a Comment