Background job manager for Yii

dev-master 2014-12-15 16:00 UTC

This package is not auto-updated.

Last update: 2022-05-09 15:04:29 UTC


README

Build Status Scrutinizer Code Quality Code Coverage Code Climate

Yiiq is a powerful Redis-backed multithreaded background job manager for Yii Framework designed with stability and simplicity in mind.

To run a job just wrap it in class and type:

Yii::app()->yiiq->enqueue('\MyJob');

And it's done!

Table of contents

Features

  • Stability
    If job crashed, daemon stays alive. If server crashed, daemon recovers its state with all unfinished jobs.
  • Multithreading
    You can run as many processes as you need.
  • Queueing
    Jobs may be grouped in different queues which handled by different processes.
  • Clarity
    You can track your job status at every point of time.
  • Scheduling
    Jobs may be executed at certain time or immediately. Once or many times.
  • Feedback
    Jobs may return result back to the extension.

Requirements

  • Unix platform
  • PHP >= 5.4
  • Redis
  • pcntl extension
  • Yii Framework >= 1.1.14
  • YiiRedis

Installation

Following steps are described assuming the fact that you have default Yii application layout, which contains two config files: main.php and console.php for web and console applications accordingly. Yiiq consists of two main parts too: framework extension and daemon. Extension queues jobs and daemon executes them. In view of the fact that daemon acts as console application, it will use console.php config file, whilst extension will use both files depending on application type in which it's being used. So pay attention to the fact that Yiiq and YiiRedis extensions must be included in both files.

At first, install Yiiq via Composer:

composer require herroffizier/yiiq:dev-master

At this point make sure that vendor/autoload.php is included in both config files.

Now we need to set up extension. Add it to your components array (must be added in both files also):

'components' => array(

    // ...

    'yiiq' => array(
        'class' => '\Yiiq\Yiiq',
        // Name to identify daemon in process list (optional)
        'name' => 'Yiiq test instance',
    ),

    // ...

),

Note, that YiiRedis extension must be loaded in both files too!

Finally, add following commands to commandMap in console.php:

'commandMap' => array(

    // ...

    // Control Yiiq command
    'yiiq' => array(
        'class' => '\Yiiq\commands\Main',
    ),
        
    // Daemon Yiiq command
    'yiiqWorker' => array(
        'class' => '\Yiiq\commands\Worker',
    ),

    // ...

),

Now it's time to run daemon. Remember, daemon is responsible for job executing, therefore it must be runnign all the time. Type following command in protected folder of your application.

./yiic yiiq start --log=yiiq.log

log parameter is optional but it highly recommended for first run at least.

Run ./yiic yiiq status to check if daemon started correctly. You should see something like this:

All processes (28235) are alive. Everything looks good.

If daemon is not running refer to application.log and yiiq.log (both stored in runtime folder) for details.

Usage

Creating jobs

To create a job you should extend \Yiiq\jobs\Payload class and implement it's run() method:

class YiiqDummyJob extends \Yiiq\jobs\Payload
{
    /**
     * Time to wait before exit.
     *
     * @var integer
     */
    public $sleep = 10;

    /**
     * This method should contain all the job logic.
     *
     * @return {mixed} all returned data will be saved in Redis 
     *                 (for non-repeatable jobs)
     */
    public function run()
    {
        Yii::trace(
            'Started dummy job '.$this->queue.':'.$this->id
            .' (sleep for '.$this->sleep.'s).'
        );
        sleep($this->sleep);
        Yii::trace('Job '.$this->queue.':'.$this->id.' completed.');
    }

}

In fact there are three types of jobs in Yiiq: simple, scheduled and repeatable. First one executed immediately, second one will execute at certain time, and third one will run infinitely in accordance with specified interval.

Simple job

To add a simple job you may use one of following calls. As you already know, this job will be executed as soon as possible and only once.

// Add YiiqDummyJob with default arguments to default queue.

// Via arguments:
$job = Yii::app()->yiiq->enqueue('\YiiqDummyJob');

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    enqueue();

// Add YiiqDummyJob with customized arguments to default queue.

// Via arguments:
$job = Yii::app()->yiiq->enqueue(
    '\YiiqDummyJob', 
    ['sleep' => 5]
);

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    withArgs(['sleep' => 5])->
    enqueue();

// Add YiiqDummyJob with customized arguments to 'custom' queue.

// Via arguments:
$job = Yii::app()->yiiq->enqueue(
    '\YiiqDummyJob', 
    ['sleep' => 5], 
    'custom'
);

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    into('custom')->
    withArgs(['sleep' => 5])->
    enqueue();

Scheduled job

To schedule a job at certain time, you must specify time or interval:

// Run job at certain time.

// Via arguments:
$job = Yii::app()->yiiq->enqueueAt(
    time() + 60, 
    'YiiqDummyJob'
);

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    runAt(time() + 60)->
    enqueue();

// Run job after 60 seconds. In fact exactly the same as above.

// Via arguments:
$job = Yii::app()->yiiq->enqueueAfter(
    60, 
    '\YiiqDummyJob'
);

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    runAt(time() + 60)->
    enqueue();

Repeatable job

To create a repeatable job, you may use following code:

// Run job each 300 seconds.

// Via arguments:
$job = Yii::app()->yiiq->enqueueEach(
    300, 
    '\YiiqDummyJob'
);

// Via method chaining:
$job = Yii::app()->yiiq->
    create('\YiiqDummyJob')->
    runEach(300)->
    enqueue();

Note that repeatable job cannot return any data back to Yiiq.