Yii2 Resque
Resque is a Redis-backed library for creating background jobs, placing those jobs on one or more queues, and processing them later., (*1)
- php pcntl extension. - Redis.io - phpredis extension for better performance, otherwise it'll automatically use Credis as fallback. - Yii 2
The preferred way to install this extension is through composer., (*2)
add, (*3)
"resque/yii2-resque": "dev-master"
to the require section of your composer.json
file., (*4)
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., (*5)
namespace app\commands; use Yii; use yii\console\Controller; use resque\lib\ResqueAutoloader; 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 = 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"); } $interval = 5; $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"); } // Child, start the worker else if(!$pid) { startWorker($QUEUE, $logLevel, $logger, $interval); break; } } } // Start a single worker 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); } } 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); } }
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), (*6)
'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 ], ... ]
Yii2-redis
ExtensionOnce the extension is installed :, (*7)
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., (*8)
Example -, (*9)
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 } }
You can put this line where ever you want to add jobs to queue, (*10)
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, (*11)
You can run job at specific time, (*12)
$time = 1332067214; Yii::$app->resque->enqueueJobAt($time, 'queue_name', 'ClassWorker', $args = []);
or run job after n second, (*13)
$in = 3600; $args = ['id' => $user->id]; Yii::$app->resque->enqueueIn($in, 'email', 'ClassWorker', $args);
This will return all job in queue (EXCLUDE all active job), (*14)
Yii::$app->resque->getQueues();
Run this command from your console/terminal :, (*15)
Start queue, (*16)
QUEUE=* php yii resque start
, (*17)
Stop queue, (*18)
QUEUE=* php yii resque stop
, (*19)