Skip to content

aakldey/yii2-resque

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yii2 Resque 2 (fixed original fork)

Resque is a Redis-backed library for creating background jobs, placing those jobs on one or more queues, and processing them later.

This was forked to fix some critical issues with original library I run into to make it work. There are a lot of things to do and I'm not sure it works for all. My configuration was: CentOS 6 server, PHP 5.6.27 with pcntl extension compiled to .so package, redis-server, yii2 2.0.6 with advanced template

Requirement

- php pcntl extension.
- Redis.io
- phpredis extension for better performance, otherwise it'll automatically use Credis as fallback.
- Yii 2

Installation

  1. The preferred way to install this extension is through composer.

    Add

    "repositories":[
            {
                "type": "git",
                "url": "https://github.com/aakldey/yii2-resque.git"
            }
        ],
    

    Either run

    php composer.phar require --prefer-dist resque/yii2-resque "*"
    

    or add

    "resque/yii2-resque": "dev-master"
    

    to the require section of your composer.json file.

  2. Create a file ResqueController.php in app/commands folder(in case of yii2-basic) or console/controllers(in case of yii2- advance) and write the following code in it.

namespace console\controllers;

use Yii; use yii\console\Controller; use resque\lib\ResqueAutoloader; use resque\lib\MonologInit\MonologInit_MonologInit; use resque\lib\Resque\ResqueScheduler_Worker; use resque\lib\Resque\Resque_Worker; /** *

  • @author Sprytechies
  • @since 2.0 / class ResqueController extends Controller { /*
    • This command echoes what you have entered as the message.

    • @param string $message the message to be echoed. */ public function actionIndex() {

      $includeFiles = getenv('INCLUDE_FILES'); if ($includeFiles) { $includeFiles = explode(',', $includeFiles); foreach ($includeFiles as $file) { require_once $file; } } if (file_exists(Yii::getAlias('@app') . '/config/console.php')) { // Yii2-Basic $config = require(Yii::getAlias('@app') . '/config/console.php'); } else { // Yii2-Advance $config = require(Yii::getAlias('@app') . '/config/main.php'); } $application = new \yii\console\Application($config);

Turn off our amazing library autoload

    spl_autoload_unregister(array('Yii', 'autoload'));

    if (file_exists(Yii::getAlias('@vendor') . '/resque/yii2-resque/ResqueAutoloader.php')) {

// Yii2-Basic require_once(Yii::getAlias('@vendor') . '/resque/yii2-resque/ResqueAutoloader.php'); } else { // Yii2-Advance require_once(Yii::getAlias('@app') . '/../vendor/resque/yii2-resque/ResqueAutoloader.php'); } ResqueAutoloader::register();

Give back the power to Yii

    spl_autoload_register(array('Yii', 'autoload'));

    $QUEUE = getenv('QUEUE');
    if (empty($QUEUE)) {
        die("Set QUEUE env var containing the list of queues to work.\n");
    }

    $REDIS_BACKEND = getenv('REDIS_BACKEND');
    $REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB');
    $REDIS_AUTH = getenv('REDIS_AUTH');

    if (!empty($REDIS_BACKEND)) {
        $REDIS_BACKEND_DB = (!empty($REDIS_BACKEND_DB)) ? $REDIS_BACKEND_DB : 0;
        Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB, $REDIS_AUTH);
    }

    $logLevel = 0;
    $LOGGING = getenv('LOGGING');
    $VERBOSE = getenv('VERBOSE');
    $VVERBOSE = getenv('VVERBOSE');
    if (!empty($LOGGING) || !empty($VERBOSE)) {
        $logLevel = Resque_Worker::LOG_NORMAL;
    } else if (!empty($VVERBOSE)) {
        $logLevel = Resque_Worker::LOG_VERBOSE;
    }

    $logger = null;
    $LOG_HANDLER = 'RotatingFile';//getenv('LOGHANDLER');
    $LOG_HANDLER_TARGET = 'worker_log.txt';//getenv('LOGHANDLERTARGET');

    if (class_exists('MonologInit_MonologInit')) {
        if (!empty($LOG_HANDLER) && !empty($LOG_HANDLER_TARGET)) {
            $logger = new MonologInit_MonologInit($LOG_HANDLER, $LOG_HANDLER_TARGET);
        } else {
            fwrite(STDOUT, '*** loghandler or logtarget is not set.' . "\n");
        }
    } else {
        fwrite(STDOUT, '*** MonologInit_MonologInit logger cannot be found, continue without loghandler.' . "\n");
    }

    $interval = 10;
    $INTERVAL = getenv('INTERVAL');
    if (!empty($INTERVAL)) {
        $interval = $INTERVAL;
    }

    $count = 1;
    $COUNT = getenv('COUNT');
    if (!empty($COUNT) && $COUNT > 1) {
        $count = $COUNT;
    }

    $PREFIX = getenv('PREFIX');
    if (!empty($PREFIX)) {
        fwrite(STDOUT, '*** Prefix set to ' . $PREFIX . "\n");
        Resque::redis()->prefix($PREFIX);
    }


    if ($count > 1) {
        for ($i = 0; $i < $count; ++$i) {
            $pid = Resque::fork();
            if ($pid == -1) {
                die("Could not fork worker " . $i . "\n");
            }
            else if (!$pid) {
                startWorker($QUEUE, $logLevel, $logger, $interval);
                break;
            }
        }
    }
    else {
        $PIDFILE = getenv('PIDFILE');
        if ($PIDFILE) {
            file_put_contents($PIDFILE, getmypid()) or
            die('Could not write PID information to ' . $PIDFILE);
        }

        $this->startWorker($QUEUE, $logLevel, $logger, $interval);
    }
}

public function actionDelayed(){

    $includeFiles = getenv('INCLUDE_FILES');
    if ($includeFiles) {
        $includeFiles = explode(',', $includeFiles);
        foreach ($includeFiles as $file) {
            require_once $file;
        }
    }
    if (file_exists(Yii::getAlias('@app') . '/config/console.php')) {
    // Yii2-Basic
        $config = require(Yii::getAlias('@app') . '/config/console.php');
    } else {
    // Yii2-Advance
        $config = require(Yii::getAlias('@app') . '/config/main.php');
    }
    $application = new \yii\console\Application($config);

    # Turn off our amazing library autoload
    spl_autoload_unregister(array('Yii', 'autoload'));

    if (file_exists(Yii::getAlias('@vendor') . '/resque/yii2-resque/ResqueAutoloader.php')) {
    // Yii2-Basic
        require_once(Yii::getAlias('@vendor') . '/resque/yii2-resque/ResqueAutoloader.php');
    } else {
    // Yii2-Advance
        require_once(Yii::getAlias('@app') . '/../vendor/resque/yii2-resque/ResqueAutoloader.php');
    }
    ResqueAutoloader::register();

    # Give back the power to Yii
    spl_autoload_register(array('Yii', 'autoload'));
    $QUEUE = getenv('QUEUE');
    if(empty($QUEUE)) {
        die("Set QUEUE env var containing the list of queues to work.\n");
    }

    $REDIS_BACKEND = getenv('REDIS_BACKEND');
    $REDIS_BACKEND_DB = getenv('REDIS_BACKEND_DB');
    $REDIS_AUTH = getenv('REDIS_AUTH');

    if(!empty($REDIS_BACKEND)) {
        $REDIS_BACKEND_DB = (!empty($REDIS_BACKEND_DB)) ? $REDIS_BACKEND_DB : 0;
        Resque::setBackend($REDIS_BACKEND, $REDIS_BACKEND_DB, $REDIS_AUTH);
    }

    // Set log level for resque-scheduler
    $logLevel = 0;
    $LOGGING = getenv('LOGGING');
    $VERBOSE = getenv('VERBOSE');
    $VVERBOSE = getenv('VVERBOSE');
    if(!empty($LOGGING) || !empty($VERBOSE)) {
        $logLevel = Resque_Worker::LOG_NORMAL;
    } else if(!empty($VVERBOSE)) {
        $logLevel = Resque_Worker::LOG_VERBOSE;
    }

    $logger = null;
    $LOG_HANDLER = getenv('LOGHANDLER');
    $LOG_HANDLER_TARGET = getenv('LOGHANDLERTARGET');

    if (class_exists('MonologInit_MonologInit')) {
        if (!empty($LOG_HANDLER) && !empty($LOG_HANDLER_TARGET)) {
            $logger = new MonologInit_MonologInit($LOG_HANDLER, $LOG_HANDLER_TARGET);
        } else {
            fwrite(STDOUT, '*** loghandler or logtarget is not set.'."\n");
        }
    } else {
        fwrite(STDOUT, '*** MonologInit_MonologInit logger cannot be found, continue without loghandler.'."\n");
    }

    // Check for jobs every $interval seconds
    $interval = 5;
    $INTERVAL = getenv('INTERVAL');
    if(!empty($INTERVAL)) {
        $interval = $INTERVAL;
    }

    $PREFIX = getenv('PREFIX');
    if(!empty($PREFIX)) {
        fwrite(STDOUT, '*** Prefix set to '.$PREFIX."\n");
        Resque::redis()->prefix($PREFIX);
    }

    $worker = new ResqueScheduler_Worker();
    if (!empty($logger)) {
        $worker->registerLogger($logger);
    } else {
        fwrite(STDOUT, "*** Starting scheduler worker\n");
    }
    $worker->logLevel = $logLevel;

    $PIDFILE = getenv('PIDFILE');
    if ($PIDFILE) {
        file_put_contents($PIDFILE, getmypid()) or
        die('Could not write PID information to ' . $PIDFILE);
    }

    $worker->work($interval);

}

function startWorker($QUEUE, $logLevel, $logger, $interval)
{
    $queues = explode(',', $QUEUE);
    $worker = new Resque_Worker($queues);

    if (!empty($logger)) {
        $worker->registerLogger($logger);
    } else {
        fwrite(STDOUT, '*** Starting worker ' . $worker . "\n");
    }

    $worker->logLevel = $logLevel;
    $worker->work($interval);
}

}

?>

```
  1. Add these in your config/web.php and in your config/console.php(in case of yii2-basic) or console/config/main.php and common/config/main-local.php (in case of yii2- advance)

    'components' => [
        ...
        'resque' => [ 
            'class' => '\resque\RResque', 
            'server' => 'localhost',     // Redis server address
            'port' => '6379',            // Redis server port
            'database' => 0,             // Redis database number
            'password' => '',            // Redis password auth, set to '' or null when no auth needed
        ], 
        ...
    ]
  2. Make sure you have already installed Yii2-redis Extension

Usage

Once the extension is installed :

  1. Create a folder components in your app(yii2-basic).in case of yii2-advance template create this folder inside app(like frontend) You can put all your class files into this components folder.Change namespace as per your application.

    Example -

    namespace app\components;
    class ClassWorker
    {
        public function setUp()
        {
            # Set up environment for this job
        }
    
        public function perform()
        {
    
            echo "Hello World";
            # Run task
        }
    
        public function tearDown()
        {
            # Remove environment for this job
        }
    }

Create job and Workers ----------------------

You can put this line where ever you want to add jobs to queue
```php
    Yii::$app->resque->createJob('queue_name', 'ClassWorker', $args = []);
```
Put your workers inside `components` folder, e.g you want to create worker with name SendEmail then you can create file inside `components` folder and name it SendEmail.php, class inside this file must be SendEmail

Create Delayed Job ------------------

You can run job at specific time
```php
    $time = 1332067214;
    Yii::$app->resque->enqueueJobAt($time, 'queue_name', 'ClassWorker', $args = []);
```
or run job after n second
```php
    $in = 3600;
    $args = ['id' => $user->id];    
    Yii::$app->resque->enqueueJobIn($in, 'email', 'ClassWorker', $args);
```
Get Current Queues
------------------

This will return all job in queue (EXCLUDE all active job)
```php
Yii::$app->resque->getQueues();
```
Start workers
----------------------

Run this command from different terminals :

`QUEUE=* php yii resque`
`QUEUE=* php yii resque/delayed`

Or in background with nohup:

`QUEUE=* nohup php yii resque`
`QUEUE=* nohup php yii resque/delayed`

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • PHP 100.0%