update v 1.0.7.5

This commit is contained in:
Sujit Prasad
2016-06-13 20:41:55 +05:30
parent aa9786d829
commit 283d97e3ea
5078 changed files with 339851 additions and 175995 deletions

View File

@@ -1,143 +1,143 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Pheanstalk\Pheanstalk;
use Pheanstalk\Job as PheanstalkJob;
use Illuminate\Queue\Jobs\BeanstalkdJob;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class BeanstalkdQueue extends Queue implements QueueContract {
class BeanstalkdQueue extends Queue implements QueueContract
{
/**
* The Pheanstalk instance.
*
* @var \Pheanstalk\Pheanstalk
*/
protected $pheanstalk;
/**
* The Pheanstalk instance.
*
* @var \Pheanstalk_Pheanstalk
*/
protected $pheanstalk;
/**
* The name of the default tube.
*
* @var string
*/
protected $default;
/**
* The name of the default tube.
*
* @var string
*/
protected $default;
/**
* The "time to run" for all pushed jobs.
*
* @var int
*/
protected $timeToRun;
/**
* The "time to run" for all pushed jobs.
*
* @var int
*/
protected $timeToRun;
/**
* Create a new Beanstalkd queue instance.
*
* @param \Pheanstalk\Pheanstalk $pheanstalk
* @param string $default
* @param int $timeToRun
* @return void
*/
public function __construct(Pheanstalk $pheanstalk, $default, $timeToRun)
{
$this->default = $default;
$this->timeToRun = $timeToRun;
$this->pheanstalk = $pheanstalk;
}
/**
* Create a new Beanstalkd queue instance.
*
* @param \Pheanstalk\Pheanstalk $pheanstalk
* @param string $default
* @param int $timeToRun
* @return void
*/
public function __construct(Pheanstalk $pheanstalk, $default, $timeToRun)
{
$this->default = $default;
$this->timeToRun = $timeToRun;
$this->pheanstalk = $pheanstalk;
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
return $this->pheanstalk->useTube($this->getQueue($queue))->put(
$payload, Pheanstalk::DEFAULT_PRIORITY, Pheanstalk::DEFAULT_DELAY, $this->timeToRun
);
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
return $this->pheanstalk->useTube($this->getQueue($queue))->put(
$payload, Pheanstalk::DEFAULT_PRIORITY, Pheanstalk::DEFAULT_DELAY, $this->timeToRun
);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
$pheanstalk = $this->pheanstalk->useTube($this->getQueue($queue));
$pheanstalk = $this->pheanstalk->useTube($this->getQueue($queue));
return $pheanstalk->put($payload, Pheanstalk::DEFAULT_PRIORITY, $this->getSeconds($delay), $this->timeToRun);
}
return $pheanstalk->put($payload, Pheanstalk::DEFAULT_PRIORITY, $this->getSeconds($delay), $this->timeToRun);
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
$job = $this->pheanstalk->watchOnly($queue)->reserve(0);
$job = $this->pheanstalk->watchOnly($queue)->reserve(0);
if ($job instanceof PheanstalkJob) {
return new BeanstalkdJob($this->container, $this->pheanstalk, $job, $queue);
}
}
if ($job instanceof PheanstalkJob)
{
return new BeanstalkdJob($this->container, $this->pheanstalk, $job, $queue);
}
}
/**
* Delete a message from the Beanstalk queue.
*
* @param string $queue
* @param string $id
* @return void
*/
public function deleteMessage($queue, $id)
{
$this->pheanstalk->useTube($this->getQueue($queue))->delete($id);
}
/**
* Delete a message from the Beanstalk queue.
*
* @param string $queue
* @param string $id
* @return void
*/
public function deleteMessage($queue, $id)
{
$this->pheanstalk->useTube($this->getQueue($queue))->delete($id);
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
public function getQueue($queue)
{
return $queue ?: $this->default;
}
/**
* Get the underlying Pheanstalk instance.
*
* @return \Pheanstalk_Pheanstalk
*/
public function getPheanstalk()
{
return $this->pheanstalk;
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
public function getQueue($queue)
{
return $queue ?: $this->default;
}
/**
* Get the underlying Pheanstalk instance.
*
* @return \Pheanstalk\Pheanstalk
*/
public function getPheanstalk()
{
return $this->pheanstalk;
}
}

View File

@@ -1,82 +1,78 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Bus\Dispatcher;
class CallQueuedHandler {
class CallQueuedHandler
{
/**
* The bus dispatcher implementation.
*
* @var \Illuminate\Contracts\Bus\Dispatcher
*/
protected $dispatcher;
/**
* The bus dispatcher implementation.
*
* @var \Illuminate\Contracts\Bus\Dispatcher
*/
protected $dispatcher;
/**
* Create a new handler instance.
*
* @param \Illuminate\Contracts\Bus\Dispatcher $dispatcher
* @return void
*/
public function __construct(Dispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
/**
* Create a new handler instance.
*
* @param \Illuminate\Contracts\Bus\Dispatcher
* @return void
*/
public function __construct(Dispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
/**
* Handle the queued job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function call(Job $job, array $data)
{
$command = $this->setJobInstanceIfNecessary(
$job, unserialize($data['command'])
);
/**
* Handle the queued job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function call(Job $job, array $data)
{
$command = $this->setJobInstanceIfNecessary(
$job, unserialize($data['command'])
);
$this->dispatcher->dispatchNow($command);
$this->dispatcher->dispatchNow($command, function($handler) use ($job)
{
$this->setJobInstanceIfNecessary($job, $handler);
});
if (! $job->isDeletedOrReleased()) {
$job->delete();
}
}
if ( ! $job->isDeletedOrReleased())
{
$job->delete();
}
}
/**
* Set the job instance of the given class if necessary.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param mixed $instance
* @return mixed
*/
protected function setJobInstanceIfNecessary(Job $job, $instance)
{
if (in_array('Illuminate\Queue\InteractsWithQueue', class_uses_recursive(get_class($instance)))) {
$instance->setJob($job);
}
/**
* Set the job instance of the given class if necessary.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param mixed $instance
* @return mixed
*/
protected function setJobInstanceIfNecessary(Job $job, $instance)
{
if (in_array('Illuminate\Queue\InteractsWithQueue', class_uses_recursive(get_class($instance))))
{
$instance->setJob($job);
}
return $instance;
}
return $instance;
}
/**
* Call the failed method on the job instance.
*
* @return void
*/
public function failed(array $data)
{
$handler = $this->dispatcher->resolveHandler($command = unserialize($data['command']));
if (method_exists($handler, 'failed'))
{
call_user_func([$handler, 'failed'], $command);
}
}
/**
* Call the failed method on the job instance.
*
* @param array $data
* @return void
*/
public function failed(array $data)
{
$command = unserialize($data['command']);
if (method_exists($command, 'failed')) {
$command->failed();
}
}
}

View File

@@ -1,182 +1,183 @@
<?php namespace Illuminate\Queue\Capsule;
<?php
namespace Illuminate\Queue\Capsule;
use Illuminate\Queue\QueueManager;
use Illuminate\Container\Container;
use Illuminate\Queue\QueueServiceProvider;
use Illuminate\Support\Traits\CapsuleManagerTrait;
class Manager {
class Manager
{
use CapsuleManagerTrait;
use CapsuleManagerTrait;
/**
* The queue manager instance.
*
* @var \Illuminate\Queue\QueueManager
*/
protected $manager;
/**
* The queue manager instance.
*
* @var \Illuminate\Queue\QueueManager
*/
protected $manager;
/**
* Create a new queue capsule manager.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function __construct(Container $container = null)
{
$this->setupContainer($container ?: new Container);
/**
* Create a new queue capsule manager.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function __construct(Container $container = null)
{
$this->setupContainer($container ?: new Container);
// Once we have the container setup, we will setup the default configuration
// options in the container "config" bindings. This just makes this queue
// manager behave correctly since all the correct binding are in place.
$this->setupDefaultConfiguration();
// Once we have the container setup, we will setup the default configuration
// options in the container "config" bindings. This just makes this queue
// manager behave correctly since all the correct binding are in place.
$this->setupDefaultConfiguration();
$this->setupManager();
$this->setupManager();
$this->registerConnectors();
}
$this->registerConnectors();
}
/**
* Setup the default queue configuration options.
*
* @return void
*/
protected function setupDefaultConfiguration()
{
$this->container['config']['queue.default'] = 'default';
}
/**
* Setup the default queue configuration options.
*
* @return void
*/
protected function setupDefaultConfiguration()
{
$this->container['config']['queue.default'] = 'default';
}
/**
* Build the queue manager instance.
*
* @return void
*/
protected function setupManager()
{
$this->manager = new QueueManager($this->container);
}
/**
* Build the queue manager instance.
*
* @return void
*/
protected function setupManager()
{
$this->manager = new QueueManager($this->container);
}
/**
* Register the default connectors that the component ships with.
*
* @return void
*/
protected function registerConnectors()
{
$provider = new QueueServiceProvider($this->container);
/**
* Register the default connectors that the component ships with.
*
* @return void
*/
protected function registerConnectors()
{
$provider = new QueueServiceProvider($this->container);
$provider->registerConnectors($this->manager);
}
$provider->registerConnectors($this->manager);
}
/**
* Get a connection instance from the global manager.
*
* @param string $connection
* @return \Illuminate\Contracts\Queue\Queue
*/
public static function connection($connection = null)
{
return static::$instance->getConnection($connection);
}
/**
* Get a connection instance from the global manager.
*
* @param string $connection
* @return \Illuminate\Contracts\Queue\Queue
*/
public static function connection($connection = null)
{
return static::$instance->getConnection($connection);
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function push($job, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->push($job, $data, $queue);
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function push($job, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->push($job, $data, $queue);
}
/**
* Push a new an array of jobs onto the queue.
*
* @param array $jobs
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function bulk($jobs, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->bulk($jobs, $data, $queue);
}
/**
* Push a new an array of jobs onto the queue.
*
* @param array $jobs
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function bulk($jobs, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->bulk($jobs, $data, $queue);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function later($delay, $job, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->later($delay, $job, $data, $queue);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @param string $connection
* @return mixed
*/
public static function later($delay, $job, $data = '', $queue = null, $connection = null)
{
return static::$instance->connection($connection)->later($delay, $job, $data, $queue);
}
/**
* Get a registered connection instance.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
public function getConnection($name = null)
{
return $this->manager->connection($name);
}
/**
* Get a registered connection instance.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
public function getConnection($name = null)
{
return $this->manager->connection($name);
}
/**
* Register a connection with the manager.
*
* @param array $config
* @param string $name
* @return void
*/
public function addConnection(array $config, $name = 'default')
{
$this->container['config']["queue.connections.{$name}"] = $config;
}
/**
* Register a connection with the manager.
*
* @param array $config
* @param string $name
* @return void
*/
public function addConnection(array $config, $name = 'default')
{
$this->container['config']["queue.connections.{$name}"] = $config;
}
/**
* Get the queue manager instance.
*
* @return \Illuminate\Queue\QueueManager
*/
public function getQueueManager()
{
return $this->manager;
}
/**
* Get the queue manager instance.
*
* @return \Illuminate\Queue\QueueManager
*/
public function getQueueManager()
{
return $this->manager;
}
/**
* Pass dynamic instance methods to the manager.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array(array($this->manager, $method), $parameters);
}
/**
* Dynamically pass methods to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(static::connection(), $method), $parameters);
}
/**
* Pass dynamic instance methods to the manager.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->manager, $method], $parameters);
}
/**
* Dynamically pass methods to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
return call_user_func_array([static::connection(), $method], $parameters);
}
}

View File

@@ -1,24 +1,26 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Pheanstalk\Pheanstalk;
use Illuminate\Support\Arr;
use Pheanstalk\PheanstalkInterface;
use Illuminate\Queue\BeanstalkdQueue;
class BeanstalkdConnector implements ConnectorInterface {
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$pheanstalk = new Pheanstalk($config['host'], array_get($config, 'port', PheanstalkInterface::DEFAULT_PORT));
return new BeanstalkdQueue(
$pheanstalk, $config['queue'], array_get($config, 'ttr', Pheanstalk::DEFAULT_TTR)
);
}
class BeanstalkdConnector implements ConnectorInterface
{
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$pheanstalk = new Pheanstalk($config['host'], Arr::get($config, 'port', PheanstalkInterface::DEFAULT_PORT));
return new BeanstalkdQueue(
$pheanstalk, $config['queue'], Arr::get($config, 'ttr', Pheanstalk::DEFAULT_TTR)
);
}
}

View File

@@ -1,13 +1,14 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
interface ConnectorInterface {
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config);
namespace Illuminate\Queue\Connectors;
interface ConnectorInterface
{
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config);
}

View File

@@ -1,42 +1,44 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Illuminate\Support\Arr;
use Illuminate\Queue\DatabaseQueue;
use Illuminate\Database\ConnectionResolverInterface;
class DatabaseConnector implements ConnectorInterface {
class DatabaseConnector implements ConnectorInterface
{
/**
* Database connections.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected $connections;
/**
* Database connections.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected $connections;
/**
* Create a new connector instance.
*
* @param \Illuminate\Database\ConnectionResolverInterface $connections
* @return void
*/
public function __construct(ConnectionResolverInterface $connections)
{
$this->connections = $connections;
}
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new DatabaseQueue(
$this->connections->connection(array_get($config, 'connection')),
$config['table'],
$config['queue'],
array_get($config, 'expire', 60)
);
}
/**
* Create a new connector instance.
*
* @param \Illuminate\Database\ConnectionResolverInterface $connections
* @return void
*/
public function __construct(ConnectionResolverInterface $connections)
{
$this->connections = $connections;
}
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new DatabaseQueue(
$this->connections->connection(Arr::get($config, 'connection')),
$config['table'],
$config['queue'],
Arr::get($config, 'expire', 60)
);
}
}

View File

@@ -1,59 +0,0 @@
<?php namespace Illuminate\Queue\Connectors;
use IronMQ;
use Illuminate\Http\Request;
use Illuminate\Queue\IronQueue;
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
class IronConnector implements ConnectorInterface {
/**
* The encrypter instance.
*
* @var \Illuminate\Encryption\Encrypter
*/
protected $crypt;
/**
* The current request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* Create a new Iron connector instance.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $crypt
* @param \Illuminate\Http\Request $request
* @return void
*/
public function __construct(EncrypterContract $crypt, Request $request)
{
$this->crypt = $crypt;
$this->request = $request;
}
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$ironConfig = array('token' => $config['token'], 'project_id' => $config['project']);
if (isset($config['host'])) $ironConfig['host'] = $config['host'];
$iron = new IronMQ($ironConfig);
if (isset($config['ssl_verifypeer']))
{
$iron->ssl_verifypeer = $config['ssl_verifypeer'];
}
return new IronQueue($iron, $this->request, $config['queue'], $config['encrypt']);
}
}

View File

@@ -1,18 +1,19 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Illuminate\Queue\NullQueue;
class NullConnector implements ConnectorInterface {
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new NullQueue;
}
class NullConnector implements ConnectorInterface
{
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new NullQueue;
}
}

View File

@@ -1,52 +1,54 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Illuminate\Support\Arr;
use Illuminate\Redis\Database;
use Illuminate\Queue\RedisQueue;
class RedisConnector implements ConnectorInterface {
class RedisConnector implements ConnectorInterface
{
/**
* The Redis database instance.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* The Redis database instance.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* The connection name.
*
* @var string
*/
protected $connection;
/**
* The connection name.
*
* @var string
*/
protected $connection;
/**
* Create a new Redis queue connector instance.
*
* @param \Illuminate\Redis\Database $redis
* @param string|null $connection
* @return void
*/
public function __construct(Database $redis, $connection = null)
{
$this->redis = $redis;
$this->connection = $connection;
}
/**
* Create a new Redis queue connector instance.
*
* @param \Illuminate\Redis\Database $redis
* @param string|null $connection
* @return void
*/
public function __construct(Database $redis, $connection = null)
{
$this->redis = $redis;
$this->connection = $connection;
}
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$queue = new RedisQueue(
$this->redis, $config['queue'], Arr::get($config, 'connection', $this->connection)
);
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$queue = new RedisQueue(
$this->redis, $config['queue'], array_get($config, 'connection', $this->connection)
);
$queue->setExpire(array_get($config, 'expire', 60));
return $queue;
}
$queue->setExpire(Arr::get($config, 'expire', 60));
return $queue;
}
}

View File

@@ -1,21 +1,46 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Aws\Sqs\SqsClient;
use Illuminate\Support\Arr;
use Illuminate\Queue\SqsQueue;
class SqsConnector implements ConnectorInterface {
class SqsConnector implements ConnectorInterface
{
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$config = $this->getDefaultConfiguration($config);
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
$sqs = SqsClient::factory($config);
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
}
return new SqsQueue($sqs, $config['queue']);
}
return new SqsQueue(
new SqsClient($config), $config['queue'], Arr::get($config, 'prefix', '')
);
}
/**
* Get the default configuration for SQS.
*
* @param array $config
* @return array
*/
protected function getDefaultConfiguration(array $config)
{
return array_merge([
'version' => 'latest',
'http' => [
'timeout' => 60,
'connect_timeout' => 60,
],
], $config);
}
}

View File

@@ -1,18 +1,19 @@
<?php namespace Illuminate\Queue\Connectors;
<?php
namespace Illuminate\Queue\Connectors;
use Illuminate\Queue\SyncQueue;
class SyncConnector implements ConnectorInterface {
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new SyncQueue;
}
class SyncConnector implements ConnectorInterface
{
/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new SyncQueue;
}
}

View File

@@ -1,85 +1,91 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Foundation\Composer;
use Illuminate\Support\Composer;
use Illuminate\Filesystem\Filesystem;
class FailedTableCommand extends Command {
class FailedTableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed-table';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed-table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the failed queue jobs database table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the failed queue jobs database table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* @var \Illuminate\Support\Composer
*/
protected $composer;
/**
* @var \Illuminate\Foundation\Composer
*/
protected $composer;
/**
* Create a new failed queue jobs table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
/**
* Create a new failed queue jobs table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
$this->files = $files;
$this->composer = $composer;
}
$this->files = $files;
$this->composer = $composer;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$table = $this->laravel['config']['queue.failed.table'];
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$fullPath = $this->createBaseMigration();
$tableClassName = Str::studly($table);
$table = $this->laravel['config']['queue.failed.table'];
$fullPath = $this->createBaseMigration($table);
$stub = str_replace(
'{{table}}', $table, $this->files->get(__DIR__.'/stubs/failed_jobs.stub')
);
$stub = str_replace(
['{{table}}', '{{tableClassName}}'], [$table, $tableClassName], $this->files->get(__DIR__.'/stubs/failed_jobs.stub')
);
$this->files->put($fullPath, $stub);
$this->files->put($fullPath, $stub);
$this->info('Migration created successfully!');
$this->info('Migration created successfully!');
$this->composer->dumpAutoloads();
}
$this->composer->dumpAutoloads();
}
/**
* Create a base migration file for the table.
*
* @return string
*/
protected function createBaseMigration()
{
$name = 'create_failed_jobs_table';
/**
* Create a base migration file for the table.
*
* @param string $table
* @return string
*/
protected function createBaseMigration($table = 'failed_jobs')
{
$name = 'create_'.$table.'_table';
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
}

View File

@@ -1,33 +1,34 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
class FlushFailedCommand extends Command {
class FlushFailedCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:flush';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:flush';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush all of the failed queue jobs';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Flush all of the failed queue jobs';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['queue.failer']->flush();
$this->info('All failed jobs deleted successfully!');
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['queue.failer']->flush();
$this->info('All failed jobs deleted successfully!');
}
}

View File

@@ -1,51 +1,49 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
class ForgetFailedCommand extends Command {
class ForgetFailedCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:forget';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:forget';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete a failed queue job';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete a failed queue job';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
if ($this->laravel['queue.failer']->forget($this->argument('id')))
{
$this->info('Failed job deleted successfully!');
}
else
{
$this->error('No failed job matches the given ID.');
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('id', InputArgument::REQUIRED, 'The ID of the failed job'),
);
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
if ($this->laravel['queue.failer']->forget($this->argument('id'))) {
$this->info('Failed job deleted successfully!');
} else {
$this->error('No failed job matches the given ID.');
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['id', InputArgument::REQUIRED, 'The ID of the failed job'],
];
}
}

View File

@@ -1,62 +1,113 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Support\Arr;
use Illuminate\Console\Command;
class ListFailedCommand extends Command {
class ListFailedCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:failed';
/**
* The console command description.
*
* @var string
*/
protected $description = 'List all of the failed queue jobs';
/**
* The console command description.
*
* @var string
*/
protected $description = 'List all of the failed queue jobs';
/**
* The table headers for the command.
*
* @var array
*/
protected $headers = ['ID', 'Connection', 'Queue', 'Class', 'Failed At'];
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$rows = array();
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$jobs = $this->getFailedJobs();
foreach ($this->laravel['queue.failer']->all() as $failed)
{
$rows[] = $this->parseFailedJob((array) $failed);
}
if (count($jobs) == 0) {
return $this->info('No failed jobs!');
}
if (count($rows) == 0)
{
return $this->info('No failed jobs!');
}
$this->displayFailedJobs($jobs);
}
$table = $this->getHelperSet()->get('table');
/**
* Compile the failed jobs into a displayable format.
*
* @return array
*/
protected function getFailedJobs()
{
$results = [];
$table->setHeaders(array('ID', 'Connection', 'Queue', 'Class', 'Failed At'))
->setRows($rows)
->render($this->output);
}
foreach ($this->laravel['queue.failer']->all() as $failed) {
$results[] = $this->parseFailedJob((array) $failed);
}
/**
* Parse the failed job row.
*
* @param array $failed
* @return array
*/
protected function parseFailedJob(array $failed)
{
$row = array_values(array_except($failed, array('payload')));
return array_filter($results);
}
array_splice($row, 3, 0, array_get(json_decode($failed['payload'], true), 'job'));
/**
* Parse the failed job row.
*
* @param array $failed
* @return array
*/
protected function parseFailedJob(array $failed)
{
$row = array_values(Arr::except($failed, ['payload']));
return $row;
}
array_splice($row, 3, 0, $this->extractJobName($failed['payload']));
return $row;
}
/**
* Extract the failed job name from payload.
*
* @param string $payload
* @return string|null
*/
private function extractJobName($payload)
{
$payload = json_decode($payload, true);
if ($payload && (! isset($payload['data']['command']))) {
return Arr::get($payload, 'job');
}
if ($payload && isset($payload['data']['command'])) {
preg_match('/"([^"]+)"/', $payload['data']['command'], $matches);
if (isset($matches[1])) {
return $matches[1];
} else {
return Arr::get($payload, 'job');
}
}
}
/**
* Display the failed jobs in the console.
*
* @param array $jobs
* @return void
*/
protected function displayFailedJobs(array $jobs)
{
$this->table($this->headers, $jobs);
}
}

View File

@@ -1,145 +1,144 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Queue\Listener;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class ListenCommand extends Command {
class ListenCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:listen';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:listen';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Listen to a given queue';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Listen to a given queue';
/**
* The queue listener instance.
*
* @var \Illuminate\Queue\Listener
*/
protected $listener;
/**
* The queue listener instance.
*
* @var \Illuminate\Queue\Listener
*/
protected $listener;
/**
* Create a new queue listen command.
*
* @param \Illuminate\Queue\Listener $listener
* @return void
*/
public function __construct(Listener $listener)
{
parent::__construct();
/**
* Create a new queue listen command.
*
* @param \Illuminate\Queue\Listener $listener
* @return void
*/
public function __construct(Listener $listener)
{
parent::__construct();
$this->listener = $listener;
}
$this->listener = $listener;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->setListenerOptions();
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->setListenerOptions();
$delay = $this->input->getOption('delay');
$delay = $this->input->getOption('delay');
// The memory limit is the amount of memory we will allow the script to occupy
// before killing it and letting a process manager restart it for us, which
// is to protect us against any memory leaks that will be in the scripts.
$memory = $this->input->getOption('memory');
// The memory limit is the amount of memory we will allow the script to occupy
// before killing it and letting a process manager restart it for us, which
// is to protect us against any memory leaks that will be in the scripts.
$memory = $this->input->getOption('memory');
$connection = $this->input->getArgument('connection');
$connection = $this->input->getArgument('connection');
$timeout = $this->input->getOption('timeout');
$timeout = $this->input->getOption('timeout');
// We need to get the right queue for the connection which is set in the queue
// configuration file for the application. We will pull it based on the set
// connection being run for the queue operation currently being executed.
$queue = $this->getQueue($connection);
// We need to get the right queue for the connection which is set in the queue
// configuration file for the application. We will pull it based on the set
// connection being run for the queue operation currently being executed.
$queue = $this->getQueue($connection);
$this->listener->listen(
$connection, $queue, $delay, $memory, $timeout
);
}
$this->listener->listen(
$connection, $queue, $delay, $memory, $timeout
);
}
/**
* Get the name of the queue connection to listen on.
*
* @param string $connection
* @return string
*/
protected function getQueue($connection)
{
if (is_null($connection)) {
$connection = $this->laravel['config']['queue.default'];
}
/**
* Get the name of the queue connection to listen on.
*
* @param string $connection
* @return string
*/
protected function getQueue($connection)
{
if (is_null($connection))
{
$connection = $this->laravel['config']['queue.default'];
}
$queue = $this->laravel['config']->get("queue.connections.{$connection}.queue", 'default');
$queue = $this->laravel['config']->get("queue.connections.{$connection}.queue", 'default');
return $this->input->getOption('queue') ?: $queue;
}
return $this->input->getOption('queue') ?: $queue;
}
/**
* Set the options on the queue listener.
*
* @return void
*/
protected function setListenerOptions()
{
$this->listener->setEnvironment($this->laravel->environment());
/**
* Set the options on the queue listener.
*
* @return void
*/
protected function setListenerOptions()
{
$this->listener->setEnvironment($this->laravel->environment());
$this->listener->setSleep($this->option('sleep'));
$this->listener->setSleep($this->option('sleep'));
$this->listener->setMaxTries($this->option('tries'));
$this->listener->setMaxTries($this->option('tries'));
$this->listener->setOutputHandler(function ($type, $line) {
$this->output->write($line);
});
}
$this->listener->setOutputHandler(function($type, $line)
{
$this->output->write($line);
});
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['connection', InputArgument::OPTIONAL, 'The name of connection'],
];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('connection', InputArgument::OPTIONAL, 'The name of connection'),
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on', null],
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on', null),
['delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0],
array('delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0),
['memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128],
array('memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128),
['timeout', null, InputOption::VALUE_OPTIONAL, 'Seconds a job may run before timing out', 60],
array('timeout', null, InputOption::VALUE_OPTIONAL, 'Seconds a job may run before timing out', 60),
array('sleep', null, InputOption::VALUE_OPTIONAL, 'Seconds to wait before checking queue for jobs', 3),
array('tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0),
);
}
['sleep', null, InputOption::VALUE_OPTIONAL, 'Seconds to wait before checking queue for jobs', 3],
['tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0],
];
}
}

View File

@@ -1,33 +1,34 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Console\Command;
class RestartCommand extends Command {
class RestartCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:restart';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:restart';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Restart queue worker daemons after their current job';
/**
* The console command description.
*
* @var string
*/
protected $description = "Restart queue worker daemons after their current job";
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['cache']->forever('illuminate:queue:restart', time());
$this->info('Broadcasting queue restart signal.');
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->laravel['cache']->forever('illuminate:queue:restart', time());
$this->info('Broadcasting queue restart signal.');
}
}

View File

@@ -1,74 +1,97 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Support\Arr;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
class RetryCommand extends Command {
class RetryCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:retry';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:retry';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Retry a failed queue job';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Retry a failed queue job';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$ids = $this->argument('id');
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$failed = $this->laravel['queue.failer']->find($this->argument('id'));
if (count($ids) === 1 && $ids[0] === 'all') {
$ids = Arr::pluck($this->laravel['queue.failer']->all(), 'id');
}
if ( ! is_null($failed))
{
$failed->payload = $this->resetAttempts($failed->payload);
foreach ($ids as $id) {
$this->retryJob($id);
}
}
$this->laravel['queue']->connection($failed->connection)->pushRaw($failed->payload, $failed->queue);
/**
* Retry the queue job with the given ID.
*
* @param string $id
* @return void
*/
protected function retryJob($id)
{
$failed = $this->laravel['queue.failer']->find($id);
$this->laravel['queue.failer']->forget($failed->id);
if (! is_null($failed)) {
$failed = (object) $failed;
$this->info('The failed job has been pushed back onto the queue!');
}
else
{
$this->error('No failed job matches the given ID.');
}
}
$failed->payload = $this->resetAttempts($failed->payload);
/**
* Reset the payload attempts.
*
* @param string $payload
* @return string
*/
protected function resetAttempts($payload)
{
$payload = json_decode($payload, true);
$this->laravel['queue']->connection($failed->connection)
->pushRaw($failed->payload, $failed->queue);
if (isset($payload['attempts'])) $payload['attempts'] = 0;
$this->laravel['queue.failer']->forget($failed->id);
return json_encode($payload);
}
$this->info("The failed job [{$id}] has been pushed back onto the queue!");
} else {
$this->error("No failed job matches the given ID [{$id}].");
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('id', InputArgument::REQUIRED, 'The ID of the failed job'),
);
}
/**
* Reset the payload attempts.
*
* @param string $payload
* @return string
*/
protected function resetAttempts($payload)
{
$payload = json_decode($payload, true);
if (isset($payload['attempts'])) {
$payload['attempts'] = 1;
}
return json_encode($payload);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['id', InputArgument::IS_ARRAY, 'The ID of the failed job'],
];
}
}

View File

@@ -1,161 +0,0 @@
<?php namespace Illuminate\Queue\Console;
use Exception;
use RuntimeException;
use Illuminate\Queue\IronQueue;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class SubscribeCommand extends Command {
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:subscribe';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Subscribe a URL to an Iron.io push queue';
/**
* The queue meta information from Iron.io.
*
* @var object
*/
protected $meta;
/**
* Execute the console command.
*
* @return void
*
* @throws \RuntimeException
*/
public function fire()
{
$iron = $this->laravel['queue']->connection();
if ( ! $iron instanceof IronQueue)
{
throw new RuntimeException("Iron.io based queue must be default.");
}
$iron->getIron()->updateQueue($this->argument('queue'), $this->getQueueOptions());
$this->line('<info>Queue subscriber added:</info> <comment>'.$this->argument('url').'</comment>');
}
/**
* Get the queue options.
*
* @return array
*/
protected function getQueueOptions()
{
return array(
'push_type' => $this->getPushType(), 'subscribers' => $this->getSubscriberList(),
);
}
/**
* Get the push type for the queue.
*
* @return string
*/
protected function getPushType()
{
if ($this->option('type')) return $this->option('type');
try
{
return $this->getQueue()->push_type;
}
catch (Exception $e)
{
return 'multicast';
}
}
/**
* Get the current subscribers for the queue.
*
* @return array
*/
protected function getSubscriberList()
{
$subscribers = $this->getCurrentSubscribers();
$url = $this->argument('url');
if ( ! starts_with($url, ['http://', 'https://']))
{
$url = $this->laravel['url']->to($url);
}
$subscribers[] = array('url' => $url);
return $subscribers;
}
/**
* Get the current subscriber list.
*
* @return array
*/
protected function getCurrentSubscribers()
{
try
{
return $this->getQueue()->subscribers;
}
catch (Exception $e)
{
return array();
}
}
/**
* Get the queue information from Iron.io.
*
* @return object
*/
protected function getQueue()
{
if (isset($this->meta)) return $this->meta;
return $this->meta = $this->laravel['queue']->getIron()->getQueue($this->argument('queue'));
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('queue', InputArgument::REQUIRED, 'The name of Iron.io queue.'),
array('url', InputArgument::REQUIRED, 'The URL to be subscribed.'),
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('type', null, InputOption::VALUE_OPTIONAL, 'The push type for the queue.'),
);
}
}

View File

@@ -1,85 +1,91 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Foundation\Composer;
use Illuminate\Support\Composer;
use Illuminate\Filesystem\Filesystem;
class TableCommand extends Command {
class TableCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:table';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the queue jobs database table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a migration for the queue jobs database table';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* @var \Illuminate\Support\Composer
*/
protected $composer;
/**
* @var \Illuminate\Foundation\Composer
*/
protected $composer;
/**
* Create a new queue job table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
/**
* Create a new queue job table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files, Composer $composer)
{
parent::__construct();
$this->files = $files;
$this->composer = $composer;
}
$this->files = $files;
$this->composer = $composer;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$table = $this->laravel['config']['queue.connections.database.table'];
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$fullPath = $this->createBaseMigration();
$tableClassName = Str::studly($table);
$table = $this->laravel['config']['queue.connections.database.table'];
$fullPath = $this->createBaseMigration($table);
$stub = str_replace(
'{{table}}', $table, $this->files->get(__DIR__.'/stubs/jobs.stub')
);
$stub = str_replace(
['{{table}}', '{{tableClassName}}'], [$table, $tableClassName], $this->files->get(__DIR__.'/stubs/jobs.stub')
);
$this->files->put($fullPath, $stub);
$this->files->put($fullPath, $stub);
$this->info('Migration created successfully!');
$this->info('Migration created successfully!');
$this->composer->dumpAutoloads();
}
$this->composer->dumpAutoloads();
}
/**
* Create a base migration file for the table.
*
* @return string
*/
protected function createBaseMigration()
{
$name = 'create_jobs_table';
/**
* Create a base migration file for the table.
*
* @param string $table
* @return string
*/
protected function createBaseMigration($table = 'jobs')
{
$name = 'create_'.$table.'_table';
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
$path = $this->laravel->databasePath().'/migrations';
return $this->laravel['migration.creator']->create($name, $path);
}
}

View File

@@ -1,180 +1,194 @@
<?php namespace Illuminate\Queue\Console;
<?php
namespace Illuminate\Queue\Console;
use Carbon\Carbon;
use Illuminate\Queue\Worker;
use Illuminate\Console\Command;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessed;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class WorkCommand extends Command {
class WorkCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:work';
/**
* The console command name.
*
* @var string
*/
protected $name = 'queue:work';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process the next job on a queue';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Process the next job on a queue';
/**
* The queue worker instance.
*
* @var \Illuminate\Queue\Worker
*/
protected $worker;
/**
* The queue worker instance.
*
* @var \Illuminate\Queue\Worker
*/
protected $worker;
/**
* Create a new queue listen command.
*
* @param \Illuminate\Queue\Worker $worker
* @return void
*/
public function __construct(Worker $worker)
{
parent::__construct();
/**
* Create a new queue listen command.
*
* @param \Illuminate\Queue\Worker $worker
* @return void
*/
public function __construct(Worker $worker)
{
parent::__construct();
$this->worker = $worker;
}
$this->worker = $worker;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
if ($this->downForMaintenance() && ! $this->option('daemon')) {
return $this->worker->sleep($this->option('sleep'));
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
if ($this->downForMaintenance() && ! $this->option('daemon'))
{
return $this->worker->sleep($this->option('sleep'));
}
// We'll listen to the processed and failed events so we can write information
// to the console as jobs are processed, which will let the developer watch
// which jobs are coming through a queue and be informed on its progress.
$this->listenForEvents();
$queue = $this->option('queue');
$queue = $this->option('queue');
$delay = $this->option('delay');
$delay = $this->option('delay');
// The memory limit is the amount of memory we will allow the script to occupy
// before killing it and letting a process manager restart it for us, which
// is to protect us against any memory leaks that will be in the scripts.
$memory = $this->option('memory');
// The memory limit is the amount of memory we will allow the script to occupy
// before killing it and letting a process manager restart it for us, which
// is to protect us against any memory leaks that will be in the scripts.
$memory = $this->option('memory');
$connection = $this->argument('connection');
$connection = $this->argument('connection');
$response = $this->runWorker(
$connection, $queue, $delay, $memory, $this->option('daemon')
);
$this->runWorker(
$connection, $queue, $delay, $memory, $this->option('daemon')
);
}
// If a job was fired by the worker, we'll write the output out to the console
// so that the developer can watch live while the queue runs in the console
// window, which will also of get logged if stdout is logged out to disk.
if ( ! is_null($response['job']))
{
$this->writeOutput($response['job'], $response['failed']);
}
}
/**
* Listen for the queue events in order to update the console output.
*
* @return void
*/
protected function listenForEvents()
{
$this->laravel['events']->listen(JobProcessed::class, function ($event) {
$this->writeOutput($event->job, false);
});
/**
* Run the worker instance.
*
* @param string $connection
* @param string $queue
* @param int $delay
* @param int $memory
* @param bool $daemon
* @return array
*/
protected function runWorker($connection, $queue, $delay, $memory, $daemon = false)
{
if ($daemon)
{
$this->worker->setCache($this->laravel['cache']->driver());
$this->laravel['events']->listen(JobFailed::class, function ($event) {
$this->writeOutput($event->job, true);
});
}
$this->worker->setDaemonExceptionHandler(
$this->laravel['Illuminate\Contracts\Debug\ExceptionHandler']
);
/**
* Run the worker instance.
*
* @param string $connection
* @param string $queue
* @param int $delay
* @param int $memory
* @param bool $daemon
* @return array
*/
protected function runWorker($connection, $queue, $delay, $memory, $daemon = false)
{
$this->worker->setDaemonExceptionHandler(
$this->laravel['Illuminate\Contracts\Debug\ExceptionHandler']
);
return $this->worker->daemon(
$connection, $queue, $delay, $memory,
$this->option('sleep'), $this->option('tries')
);
}
if ($daemon) {
$this->worker->setCache($this->laravel['cache']->driver());
return $this->worker->pop(
$connection, $queue, $delay,
$this->option('sleep'), $this->option('tries')
);
}
return $this->worker->daemon(
$connection, $queue, $delay, $memory,
$this->option('sleep'), $this->option('tries')
);
}
/**
* Write the status output for the queue worker.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param bool $failed
* @return void
*/
protected function writeOutput(Job $job, $failed)
{
if ($failed)
{
$this->output->writeln('<error>Failed:</error> '.$job->getName());
}
else
{
$this->output->writeln('<info>Processed:</info> '.$job->getName());
}
}
return $this->worker->pop(
$connection, $queue, $delay,
$this->option('sleep'), $this->option('tries')
);
}
/**
* Determine if the worker should run in maintenance mode.
*
* @return bool
*/
protected function downForMaintenance()
{
if ($this->option('force')) return false;
/**
* Write the status output for the queue worker.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param bool $failed
* @return void
*/
protected function writeOutput(Job $job, $failed)
{
if ($failed) {
$this->output->writeln('<error>['.Carbon::now()->format('Y-m-d H:i:s').'] Failed:</error> '.$job->resolveName());
} else {
$this->output->writeln('<info>['.Carbon::now()->format('Y-m-d H:i:s').'] Processed:</info> '.$job->resolveName());
}
}
return $this->laravel->isDownForMaintenance();
}
/**
* Determine if the worker should run in maintenance mode.
*
* @return bool
*/
protected function downForMaintenance()
{
if ($this->option('force')) {
return false;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('connection', InputArgument::OPTIONAL, 'The name of connection', null),
);
}
return $this->laravel->isDownForMaintenance();
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on'),
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['connection', InputArgument::OPTIONAL, 'The name of connection', null],
];
}
array('daemon', null, InputOption::VALUE_NONE, 'Run the worker in daemon mode'),
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on'],
array('delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0),
['daemon', null, InputOption::VALUE_NONE, 'Run the worker in daemon mode'],
array('force', null, InputOption::VALUE_NONE, 'Force the worker to run even in maintenance mode'),
['delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0],
array('memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128),
['force', null, InputOption::VALUE_NONE, 'Force the worker to run even in maintenance mode'],
array('sleep', null, InputOption::VALUE_OPTIONAL, 'Number of seconds to sleep when no job is available', 3),
['memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128],
array('tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0),
);
}
['sleep', null, InputOption::VALUE_OPTIONAL, 'Number of seconds to sleep when no job is available', 3],
['tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0],
];
}
}

View File

@@ -3,33 +3,31 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFailedJobsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function(Blueprint $table)
{
$table->increments('id');
$table->text('connection');
$table->text('queue');
$table->text('payload');
$table->timestamp('failed_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('{{table}}');
}
class Create{{tableClassName}}Table extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function (Blueprint $table) {
$table->increments('id');
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('{{table}}');
}
}

View File

@@ -3,36 +3,35 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateJobsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function(Blueprint $table)
{
$table->bigIncrements('id');
$table->string('queue');
$table->text('payload');
$table->tinyInteger('attempts')->unsigned();
$table->tinyInteger('reserved')->unsigned();
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('{{table}}');
}
class Create{{tableClassName}}Table extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{table}}', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue');
$table->longText('payload');
$table->tinyInteger('attempts')->unsigned();
$table->tinyInteger('reserved')->unsigned();
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
$table->index(['queue', 'reserved', 'reserved_at']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('{{table}}');
}
}

View File

@@ -1,76 +1,61 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Illuminate\Support\ServiceProvider;
use Illuminate\Queue\Console\TableCommand;
use Illuminate\Queue\Console\RetryCommand;
use Illuminate\Queue\Console\ListFailedCommand;
use Illuminate\Queue\Console\FlushFailedCommand;
use Illuminate\Queue\Console\FailedTableCommand;
use Illuminate\Queue\Console\ForgetFailedCommand;
class ConsoleServiceProvider extends ServiceProvider {
class ConsoleServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('command.queue.failed', function () {
return new ListFailedCommand;
});
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('command.queue.table', function($app)
{
return new TableCommand($app['files'], $app['composer']);
});
$this->app->singleton('command.queue.retry', function () {
return new RetryCommand;
});
$this->app->singleton('command.queue.failed', function()
{
return new ListFailedCommand;
});
$this->app->singleton('command.queue.forget', function () {
return new ForgetFailedCommand;
});
$this->app->singleton('command.queue.retry', function()
{
return new RetryCommand;
});
$this->app->singleton('command.queue.flush', function () {
return new FlushFailedCommand;
});
$this->app->singleton('command.queue.forget', function()
{
return new ForgetFailedCommand;
});
$this->app->singleton('command.queue.flush', function()
{
return new FlushFailedCommand;
});
$this->app->singleton('command.queue.failed-table', function($app)
{
return new FailedTableCommand($app['files'], $app['composer']);
});
$this->commands(
'command.queue.table', 'command.queue.failed', 'command.queue.retry',
'command.queue.forget', 'command.queue.flush', 'command.queue.failed-table'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array(
'command.queue.table', 'command.queue.failed', 'command.queue.retry',
'command.queue.forget', 'command.queue.flush', 'command.queue.failed-table',
);
}
$this->commands(
'command.queue.failed', 'command.queue.retry',
'command.queue.forget', 'command.queue.flush'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'command.queue.failed', 'command.queue.retry',
'command.queue.forget', 'command.queue.flush',
];
}
}

View File

@@ -1,272 +1,341 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use DateTime;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Database\Connection;
use Illuminate\Queue\Jobs\DatabaseJob;
use Illuminate\Database\Query\Expression;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class DatabaseQueue extends Queue implements QueueContract {
class DatabaseQueue extends Queue implements QueueContract
{
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $database;
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $database;
/**
* The database table that holds the jobs.
*
* @var string
*/
protected $table;
/**
* The database table that holds the jobs.
*
* @var string
*/
protected $table;
/**
* The name of the default queue.
*
* @var string
*/
protected $default;
/**
* The name of the default queue.
*
* @var string
*/
protected $default;
/**
* The expiration time of a job.
*
* @var int|null
*/
protected $expire = 60;
/**
* The expiration time of a job.
*
* @var int|null
*/
protected $expire = 60;
/**
* Create a new database queue instance.
*
* @param \Illuminate\Database\Connection $database
* @param string $table
* @param string $default
* @param int $expire
* @return void
*/
public function __construct(Connection $database, $table, $default = 'default', $expire = 60)
{
$this->table = $table;
$this->expire = $expire;
$this->default = $default;
$this->database = $database;
}
/**
* Create a new database queue instance.
*
* @param \Illuminate\Database\Connection $database
* @param string $table
* @param string $default
* @param int $expire
* @return void
*/
public function __construct(Connection $database, $table, $default = 'default', $expire = 60)
{
$this->table = $table;
$this->expire = $expire;
$this->default = $default;
$this->database = $database;
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushToDatabase(0, $queue, $this->createPayload($job, $data));
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return void
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushToDatabase(0, $queue, $this->createPayload($job, $data));
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
return $this->pushToDatabase(0, $queue, $payload);
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
return $this->pushToDatabase(0, $queue, $payload);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return void
*/
public function later($delay, $job, $data = '', $queue = null)
{
return $this->pushToDatabase($delay, $queue, $this->createPayload($job, $data));
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return void
*/
public function later($delay, $job, $data = '', $queue = null)
{
return $this->pushToDatabase($delay, $queue, $this->createPayload($job, $data));
}
/**
* Push an array of jobs onto the queue.
*
* @param array $jobs
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function bulk($jobs, $data = '', $queue = null)
{
$queue = $this->getQueue($queue);
/**
* Release a reserved job back onto the queue.
*
* @param string $queue
* @param \StdClass $job
* @param int $delay
* @return void
*/
public function release($queue, $job, $delay)
{
return $this->pushToDatabase($delay, $queue, $job->payload, $job->attempts);
}
$availableAt = $this->getAvailableAt(0);
/**
* Push a raw payload to the database with a given delay.
*
* @param \DateTime|int $delay
* @param string|null $queue
* @param string $payload
* @param int $attempts
* @return mixed
*/
protected function pushToDatabase($delay, $queue, $payload, $attempts = 0)
{
$availableAt = $delay instanceof DateTime ? $delay : Carbon::now()->addSeconds($delay);
$records = array_map(function ($job) use ($queue, $data, $availableAt) {
return $this->buildDatabaseRecord(
$queue, $this->createPayload($job, $data), $availableAt
);
}, (array) $jobs);
return $this->database->table($this->table)->insertGetId([
'queue' => $this->getQueue($queue),
'payload' => $payload,
'attempts' => $attempts,
'reserved' => 0,
'reserved_at' => null,
'available_at' => $availableAt->getTimestamp(),
'created_at' => $this->getTime(),
]);
}
return $this->database->table($this->table)->insert($records);
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
/**
* Release a reserved job back onto the queue.
*
* @param string $queue
* @param \StdClass $job
* @param int $delay
* @return mixed
*/
public function release($queue, $job, $delay)
{
return $this->pushToDatabase($delay, $queue, $job->payload, $job->attempts);
}
if ( ! is_null($this->expire))
{
$this->releaseJobsThatHaveBeenReservedTooLong($queue);
}
/**
* Push a raw payload to the database with a given delay.
*
* @param \DateTime|int $delay
* @param string|null $queue
* @param string $payload
* @param int $attempts
* @return mixed
*/
protected function pushToDatabase($delay, $queue, $payload, $attempts = 0)
{
$attributes = $this->buildDatabaseRecord(
$this->getQueue($queue), $payload, $this->getAvailableAt($delay), $attempts
);
if ($job = $this->getNextAvailableJob($queue))
{
$this->markJobAsReserved($job->id);
return $this->database->table($this->table)->insertGetId($attributes);
}
$this->database->commit();
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
return new DatabaseJob(
$this->container, $this, $job, $queue
);
}
if (! is_null($this->expire)) {
$this->releaseJobsThatHaveBeenReservedTooLong($queue);
}
$this->database->commit();
}
$this->database->beginTransaction();
/**
* Release the jobs that have been reserved for too long.
*
* @param string $queue
* @return void
*/
protected function releaseJobsThatHaveBeenReservedTooLong($queue)
{
$expired = Carbon::now()->subSeconds($this->expire)->getTimestamp();
if ($job = $this->getNextAvailableJob($queue)) {
$this->markJobAsReserved($job->id);
$this->database->table($this->table)
->where('queue', $this->getQueue($queue))
->where('reserved', 1)
->where('reserved_at', '<=', $expired)
->update([
'reserved' => 0,
'reserved_at' => null,
'attempts' => new Expression('attempts + 1'),
]);
}
$this->database->commit();
/**
* Get the next available job for the queue.
*
* @param string|null $queue
* @return \StdClass|null
*/
protected function getNextAvailableJob($queue)
{
$this->database->beginTransaction();
return new DatabaseJob(
$this->container, $this, $job, $queue
);
}
$job = $this->database->table($this->table)
->lockForUpdate()
->where('queue', $this->getQueue($queue))
->where('reserved', 0)
->where('available_at', '<=', $this->getTime())
->orderBy('id', 'asc')
->first();
$this->database->commit();
}
return $job ? (object) $job : null;
}
/**
* Release the jobs that have been reserved for too long.
*
* @param string $queue
* @return void
*/
protected function releaseJobsThatHaveBeenReservedTooLong($queue)
{
if (random_int(1, 10) < 10) {
return;
}
/**
* Mark the given job ID as reserved.
*
* @param string $id
* @return void
*/
protected function markJobAsReserved($id)
{
$this->database->table($this->table)->where('id', $id)->update([
'reserved' => 1, 'reserved_at' => $this->getTime(),
]);
}
$this->database->beginTransaction();
/**
* Delete a reserved job from the queue.
*
* @param string $queue
* @param string $id
* @return void
*/
public function deleteReserved($queue, $id)
{
$this->database->table($this->table)->where('id', $id)->delete();
}
$stale = $this->database->table($this->table)
->lockForUpdate()
->where('queue', $this->getQueue($queue))
->where('reserved', 1)
->where('reserved_at', '<=', Carbon::now()->subSeconds($this->expire)->getTimestamp())
->get();
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
protected function getQueue($queue)
{
return $queue ?: $this->default;
}
$this->database->table($this->table)
->whereIn('id', Collection::make($stale)->pluck('id')->all())
->update([
'reserved' => 0,
'reserved_at' => null,
'attempts' => new Expression('attempts + 1'),
]);
/**
* Get the underlying database instance.
*
* @return \Illuminate\Database\Connection
*/
public function getDatabase()
{
return $this->database;
}
$this->database->commit();
}
/**
* Get the expiration time in seconds.
*
* @return int|null
*/
public function getExpire()
{
return $this->expire;
}
/**
* Get the next available job for the queue.
*
* @param string|null $queue
* @return \StdClass|null
*/
protected function getNextAvailableJob($queue)
{
$job = $this->database->table($this->table)
->lockForUpdate()
->where('queue', $this->getQueue($queue))
->where('reserved', 0)
->where('available_at', '<=', $this->getTime())
->orderBy('id', 'asc')
->first();
/**
* Set the expiration time in seconds.
*
* @param int|null $seconds
* @return void
*/
public function setExpire($seconds)
{
$this->expire = $seconds;
}
return $job ? (object) $job : null;
}
/**
* Mark the given job ID as reserved.
*
* @param string $id
* @return void
*/
protected function markJobAsReserved($id)
{
$this->database->table($this->table)->where('id', $id)->update([
'reserved' => 1, 'reserved_at' => $this->getTime(),
]);
}
/**
* Delete a reserved job from the queue.
*
* @param string $queue
* @param string $id
* @return void
*/
public function deleteReserved($queue, $id)
{
$this->database->beginTransaction();
if ($this->database->table($this->table)->lockForUpdate()->find($id)) {
$this->database->table($this->table)->where('id', $id)->delete();
}
$this->database->commit();
}
/**
* Get the "available at" UNIX timestamp.
*
* @param \DateTime|int $delay
* @return int
*/
protected function getAvailableAt($delay)
{
$availableAt = $delay instanceof DateTime ? $delay : Carbon::now()->addSeconds($delay);
return $availableAt->getTimestamp();
}
/**
* Create an array to insert for the given job.
*
* @param string|null $queue
* @param string $payload
* @param int $availableAt
* @param int $attempts
* @return array
*/
protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)
{
return [
'queue' => $queue,
'attempts' => $attempts,
'reserved' => 0,
'reserved_at' => null,
'available_at' => $availableAt,
'created_at' => $this->getTime(),
'payload' => $payload,
];
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
protected function getQueue($queue)
{
return $queue ?: $this->default;
}
/**
* Get the underlying database instance.
*
* @return \Illuminate\Database\Connection
*/
public function getDatabase()
{
return $this->database;
}
/**
* Get the expiration time in seconds.
*
* @return int|null
*/
public function getExpire()
{
return $this->expire;
}
/**
* Set the expiration time in seconds.
*
* @param int|null $seconds
* @return void
*/
public function setExpire($seconds)
{
$this->expire = $seconds;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Illuminate\Queue\Events;
class JobExceptionOccurred
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;
/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;
/**
* The data given to the job.
*
* @var array
*/
public $data;
/**
* The exception instance.
*
* @var \Throwable
*/
public $exception;
/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @param \Throwable $exception
* @return void
*/
public function __construct($connectionName, $job, $data, $exception)
{
$this->job = $job;
$this->data = $data;
$this->exception = $exception;
$this->connectionName = $connectionName;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Illuminate\Queue\Events;
class JobFailed
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;
/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;
/**
* The data given to the job.
*
* @var array
*/
public $data;
/**
* The ID of the entry in the failed jobs table.
*
* @var int|null
*/
public $failedId;
/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @param int|null $failedId
* @return void
*/
public function __construct($connectionName, $job, $data, $failedId = null)
{
$this->job = $job;
$this->data = $data;
$this->failedId = $failedId;
$this->connectionName = $connectionName;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Illuminate\Queue\Events;
class JobProcessed
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;
/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;
/**
* The data given to the job.
*
* @var array
*/
public $data;
/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function __construct($connectionName, $job, $data)
{
$this->job = $job;
$this->data = $data;
$this->connectionName = $connectionName;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Illuminate\Queue\Events;
class JobProcessing
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;
/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;
/**
* The data given to the job.
*
* @var array
*/
public $data;
/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function __construct($connectionName, $job, $data)
{
$this->job = $job;
$this->data = $data;
$this->connectionName = $connectionName;
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Illuminate\Queue\Events;
class WorkerStopping
{
//
}

View File

@@ -1,111 +1,112 @@
<?php namespace Illuminate\Queue\Failed;
<?php
namespace Illuminate\Queue\Failed;
use Carbon\Carbon;
use Illuminate\Database\ConnectionResolverInterface;
class DatabaseFailedJobProvider implements FailedJobProviderInterface {
class DatabaseFailedJobProvider implements FailedJobProviderInterface
{
/**
* The connection resolver implementation.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected $resolver;
/**
* The connection resolver implementation.
*
* @var \Illuminate\Database\ConnectionResolverInterface
*/
protected $resolver;
/**
* The database connection name.
*
* @var string
*/
protected $database;
/**
* The database connection name.
*
* @var string
*/
protected $database;
/**
* The database table.
*
* @var string
*/
protected $table;
/**
* The database table.
*
* @var string
*/
protected $table;
/**
* Create a new database failed job provider.
*
* @param \Illuminate\Database\ConnectionResolverInterface $resolver
* @param string $database
* @param string $table
* @return void
*/
public function __construct(ConnectionResolverInterface $resolver, $database, $table)
{
$this->table = $table;
$this->resolver = $resolver;
$this->database = $database;
}
/**
* Create a new database failed job provider.
*
* @param \Illuminate\Database\ConnectionResolverInterface $resolver
* @param string $database
* @param string $table
* @return void
*/
public function __construct(ConnectionResolverInterface $resolver, $database, $table)
{
$this->table = $table;
$this->resolver = $resolver;
$this->database = $database;
}
/**
* Log a failed job into storage.
*
* @param string $connection
* @param string $queue
* @param string $payload
* @return int|null
*/
public function log($connection, $queue, $payload)
{
$failed_at = Carbon::now();
/**
* Log a failed job into storage.
*
* @param string $connection
* @param string $queue
* @param string $payload
* @return void
*/
public function log($connection, $queue, $payload)
{
$failed_at = Carbon::now();
return $this->getTable()->insertGetId(compact('connection', 'queue', 'payload', 'failed_at'));
}
$this->getTable()->insert(compact('connection', 'queue', 'payload', 'failed_at'));
}
/**
* Get a list of all of the failed jobs.
*
* @return array
*/
public function all()
{
return $this->getTable()->orderBy('id', 'desc')->get();
}
/**
* Get a list of all of the failed jobs.
*
* @return array
*/
public function all()
{
return $this->getTable()->orderBy('id', 'desc')->get();
}
/**
* Get a single failed job.
*
* @param mixed $id
* @return array
*/
public function find($id)
{
return $this->getTable()->find($id);
}
/**
* Get a single failed job.
*
* @param mixed $id
* @return array
*/
public function find($id)
{
return $this->getTable()->find($id);
}
/**
* Delete a single failed job from storage.
*
* @param mixed $id
* @return bool
*/
public function forget($id)
{
return $this->getTable()->where('id', $id)->delete() > 0;
}
/**
* Delete a single failed job from storage.
*
* @param mixed $id
* @return bool
*/
public function forget($id)
{
return $this->getTable()->where('id', $id)->delete() > 0;
}
/**
* Flush all of the failed jobs from storage.
*
* @return void
*/
public function flush()
{
$this->getTable()->delete();
}
/**
* Get a new query builder instance for the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->resolver->connection($this->database)->table($this->table);
}
/**
* Flush all of the failed jobs from storage.
*
* @return void
*/
public function flush()
{
$this->getTable()->delete();
}
/**
* Get a new query builder instance for the table.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function getTable()
{
return $this->resolver->connection($this->database)->table($this->table);
}
}

View File

@@ -1,45 +1,46 @@
<?php namespace Illuminate\Queue\Failed;
<?php
interface FailedJobProviderInterface {
namespace Illuminate\Queue\Failed;
/**
* Log a failed job into storage.
*
* @param string $connection
* @param string $queue
* @param string $payload
* @return void
*/
public function log($connection, $queue, $payload);
interface FailedJobProviderInterface
{
/**
* Log a failed job into storage.
*
* @param string $connection
* @param string $queue
* @param string $payload
* @return int|null
*/
public function log($connection, $queue, $payload);
/**
* Get a list of all of the failed jobs.
*
* @return array
*/
public function all();
/**
* Get a list of all of the failed jobs.
*
* @return array
*/
public function all();
/**
* Get a single failed job.
*
* @param mixed $id
* @return array
*/
public function find($id);
/**
* Get a single failed job.
*
* @param mixed $id
* @return array
*/
public function find($id);
/**
* Delete a single failed job from storage.
*
* @param mixed $id
* @return bool
*/
public function forget($id);
/**
* Flush all of the failed jobs from storage.
*
* @return void
*/
public function flush();
/**
* Delete a single failed job from storage.
*
* @param mixed $id
* @return bool
*/
public function forget($id);
/**
* Flush all of the failed jobs from storage.
*
* @return void
*/
public function flush();
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Illuminate\Queue\Failed;
class NullFailedJobProvider implements FailedJobProviderInterface
{
/**
* Log a failed job into storage.
*
* @param string $connection
* @param string $queue
* @param string $payload
* @return int|null
*/
public function log($connection, $queue, $payload)
{
//
}
/**
* Get a list of all of the failed jobs.
*
* @return array
*/
public function all()
{
return [];
}
/**
* Get a single failed job.
*
* @param mixed $id
* @return array
*/
public function find($id)
{
//
}
/**
* Delete a single failed job from storage.
*
* @param mixed $id
* @return bool
*/
public function forget($id)
{
return true;
}
/**
* Flush all of the failed jobs from storage.
*
* @return void
*/
public function flush()
{
//
}
}

View File

@@ -2,38 +2,37 @@
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
class IlluminateQueueClosure {
class IlluminateQueueClosure
{
/**
* The encrypter instance.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $crypt;
/**
* The encrypter instance.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $crypt;
/**
* Create a new queued Closure job.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $crypt
* @return void
*/
public function __construct(EncrypterContract $crypt)
{
$this->crypt = $crypt;
}
/**
* Create a new queued Closure job.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $crypt
* @return void
*/
public function __construct(EncrypterContract $crypt)
{
$this->crypt = $crypt;
}
/**
* Fire the Closure based queue job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function fire($job, $data)
{
$closure = unserialize($this->crypt->decrypt($data['closure']));
$closure($job);
}
/**
* Fire the Closure based queue job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param array $data
* @return void
*/
public function fire($job, $data)
{
$closure = unserialize($this->crypt->decrypt($data['closure']));
$closure($job);
}
}

View File

@@ -1,64 +1,75 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Illuminate\Contracts\Queue\Job as JobContract;
trait InteractsWithQueue {
trait InteractsWithQueue
{
/**
* The underlying queue job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
protected $job;
/**
* The underlying queue job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
protected $job;
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return $this->job ? $this->job->attempts() : 1;
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
if ($this->job)
{
return $this->job->delete();
}
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
if ($this->job) {
return $this->job->delete();
}
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
if ($this->job)
{
return $this->job->release($delay);
}
}
/**
* Fail the job from the queue.
*
* @return void
*/
public function failed()
{
if ($this->job) {
return $this->job->failed();
}
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return $this->job ? $this->job->attempts() : 1;
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
if ($this->job) {
return $this->job->release($delay);
}
}
/**
* Set the base queue job instance.
*
* @param \Illuminate\Contracts\Queue\Job
* @return $this
*/
public function setJob(JobContract $job)
{
$this->job = $job;
return $this;
}
/**
* Set the base queue job instance.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return $this
*/
public function setJob(JobContract $job)
{
$this->job = $job;
return $this;
}
}

View File

@@ -1,259 +0,0 @@
<?php namespace Illuminate\Queue;
use IronMQ;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Queue\Jobs\IronJob;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class IronQueue extends Queue implements QueueContract {
/**
* The IronMQ instance.
*
* @var IronMQ
*/
protected $iron;
/**
* The current request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* The name of the default tube.
*
* @var string
*/
protected $default;
/**
* Indicates if the messages should be encrypted.
*
* @var bool
*/
protected $shouldEncrypt;
/**
* Create a new IronMQ queue instance.
*
* @param \IronMQ $iron
* @param \Illuminate\Http\Request $request
* @param string $default
* @param bool $shouldEncrypt
* @return void
*/
public function __construct(IronMQ $iron, Request $request, $default, $shouldEncrypt = false)
{
$this->iron = $iron;
$this->request = $request;
$this->default = $default;
$this->shouldEncrypt = $shouldEncrypt;
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data, $queue), $queue);
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
if ($this->shouldEncrypt) $payload = $this->crypt->encrypt($payload);
return $this->iron->postMessage($this->getQueue($queue), $payload, $options)->id;
}
/**
* Push a raw payload onto the queue after encrypting the payload.
*
* @param string $payload
* @param string $queue
* @param int $delay
* @return mixed
*/
public function recreate($payload, $queue = null, $delay)
{
$options = array('delay' => $this->getSeconds($delay));
return $this->pushRaw($payload, $queue, $options);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$delay = $this->getSeconds($delay);
$payload = $this->createPayload($job, $data, $queue);
return $this->pushRaw($payload, $queue, compact('delay'));
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
$job = $this->iron->getMessage($queue);
// If we were able to pop a message off of the queue, we will need to decrypt
// the message body, as all Iron.io messages are encrypted, since the push
// queues will be a security hazard to unsuspecting developers using it.
if ( ! is_null($job))
{
$job->body = $this->parseJobBody($job->body);
return new IronJob($this->container, $this, $job);
}
}
/**
* Delete a message from the Iron queue.
*
* @param string $queue
* @param string $id
* @return void
*/
public function deleteMessage($queue, $id)
{
$this->iron->deleteMessage($queue, $id);
}
/**
* Marshal a push queue request and fire the job.
*
* @return \Illuminate\Http\Response
*/
public function marshal()
{
$this->createPushedIronJob($this->marshalPushedJob())->fire();
return new Response('OK');
}
/**
* Marshal out the pushed job and payload.
*
* @return object
*/
protected function marshalPushedJob()
{
$r = $this->request;
$body = $this->parseJobBody($r->getContent());
return (object) array(
'id' => $r->header('iron-message-id'), 'body' => $body, 'pushed' => true,
);
}
/**
* Create a new IronJob for a pushed job.
*
* @param object $job
* @return \Illuminate\Queue\Jobs\IronJob
*/
protected function createPushedIronJob($job)
{
return new IronJob($this->container, $this, $job, true);
}
/**
* Create a payload string from the given job and data.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return string
*/
protected function createPayload($job, $data = '', $queue = null)
{
$payload = $this->setMeta(parent::createPayload($job, $data), 'attempts', 1);
return $this->setMeta($payload, 'queue', $this->getQueue($queue));
}
/**
* Parse the job body for firing.
*
* @param string $body
* @return string
*/
protected function parseJobBody($body)
{
return $this->shouldEncrypt ? $this->crypt->decrypt($body) : $body;
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
public function getQueue($queue)
{
return $queue ?: $this->default;
}
/**
* Get the underlying IronMQ instance.
*
* @return \IronMQ
*/
public function getIron()
{
return $this->iron;
}
/**
* Get the request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Set the request instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return void
*/
public function setRequest(Request $request)
{
$this->request = $request;
}
}

View File

@@ -1,153 +1,154 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use Pheanstalk\Pheanstalk;
use Illuminate\Container\Container;
use Pheanstalk\Job as PheanstalkJob;
use Illuminate\Contracts\Queue\Job as JobContract;
class BeanstalkdJob extends Job implements JobContract {
class BeanstalkdJob extends Job implements JobContract
{
/**
* The Pheanstalk instance.
*
* @var \Pheanstalk\Pheanstalk
*/
protected $pheanstalk;
/**
* The Pheanstalk instance.
*
* @var \Pheanstalk_Pheanstalk
*/
protected $pheanstalk;
/**
* The Pheanstalk job instance.
*
* @var \Pheanstalk\Job
*/
protected $job;
/**
* The Pheanstalk job instance.
*
* @var PheanstalkJob
*/
protected $job;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param Pheanstalk $pheanstalk
* @param PheanstalkJob $job
* @param string $queue
* @return void
*/
public function __construct(Container $container,
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Pheanstalk\Pheanstalk $pheanstalk
* @param \Pheanstalk\Job $job
* @param string $queue
* @return void
*/
public function __construct(Container $container,
Pheanstalk $pheanstalk,
PheanstalkJob $job,
$queue)
{
$this->job = $job;
$this->queue = $queue;
$this->container = $container;
$this->pheanstalk = $pheanstalk;
}
{
$this->job = $job;
$this->queue = $queue;
$this->container = $container;
$this->pheanstalk = $pheanstalk;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job->getData();
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job->getData();
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
$this->pheanstalk->delete($this->job);
}
$this->pheanstalk->delete($this->job);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
$priority = Pheanstalk::DEFAULT_PRIORITY;
$priority = Pheanstalk::DEFAULT_PRIORITY;
$this->pheanstalk->release($this->job, $priority, $delay);
}
$this->pheanstalk->release($this->job, $priority, $delay);
}
/**
* Bury the job in the queue.
*
* @return void
*/
public function bury()
{
$this->pheanstalk->bury($this->job);
}
/**
* Bury the job in the queue.
*
* @return void
*/
public function bury()
{
$this->pheanstalk->bury($this->job);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
$stats = $this->pheanstalk->statsJob($this->job);
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
$stats = $this->pheanstalk->statsJob($this->job);
return (int) $stats->reserves;
}
return (int) $stats->reserves;
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job->getId();
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job->getId();
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the underlying Pheanstalk instance.
*
* @return \Pheanstalk_Pheanstalk
*/
public function getPheanstalk()
{
return $this->pheanstalk;
}
/**
* Get the underlying Pheanstalk job.
*
* @return PheanstalkJob
*/
public function getPheanstalkJob()
{
return $this->job;
}
/**
* Get the underlying Pheanstalk instance.
*
* @return \Pheanstalk\Pheanstalk
*/
public function getPheanstalk()
{
return $this->pheanstalk;
}
/**
* Get the underlying Pheanstalk job.
*
* @return \Pheanstalk\Job
*/
public function getPheanstalkJob()
{
return $this->job;
}
}

View File

@@ -1,138 +1,139 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use Illuminate\Queue\DatabaseQueue;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;
class DatabaseJob extends Job implements JobContract {
class DatabaseJob extends Job implements JobContract
{
/**
* The database queue instance.
*
* @var \Illuminate\Queue\DatabaseQueue
*/
protected $database;
/**
* The database queue instance.
*
* @var \Illuminate\Queue\DatabaseQueue
*/
protected $database;
/**
* The database job payload.
*
* @var \StdClass
*/
protected $job;
/**
* The database job payload.
*
* @var \StdClass
*/
protected $job;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Queue\DatabaseQueue $database
* @param \StdClass $job
* @param string $queue
* @return void
*/
public function __construct(Container $container, DatabaseQueue $database, $job, $queue)
{
$this->job = $job;
$this->queue = $queue;
$this->database = $database;
$this->container = $container;
$this->job->attempts = $this->job->attempts + 1;
}
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Queue\DatabaseQueue $database
* @param \StdClass $job
* @param string $queue
* @return void
*/
public function __construct(Container $container, DatabaseQueue $database, $job, $queue)
{
$this->job = $job;
$this->queue = $queue;
$this->database = $database;
$this->container = $container;
$this->job->attempts = $this->job->attempts + 1;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->job->payload, true));
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->job->payload, true));
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
$this->database->deleteReserved($this->queue, $this->job->id);
}
$this->database->deleteReserved($this->queue, $this->job->id);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
$this->delete();
$this->delete();
$this->database->release($this->queue, $this->job, $delay);
}
$this->database->release($this->queue, $this->job, $delay);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return (int) $this->job->attempts;
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return (int) $this->job->attempts;
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job->id;
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job->id;
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job->payload;
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job->payload;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the underlying queue driver instance.
*
* @return \Illuminate\Queue\DatabaseQueue
*/
public function getDatabaseQueue()
{
return $this->database;
}
/**
* Get the underlying database job.
*
* @return \StdClass
*/
public function getDatabaseJob()
{
return $this->job;
}
/**
* Get the underlying queue driver instance.
*
* @return \Illuminate\Queue\DatabaseQueue
*/
public function getDatabaseQueue()
{
return $this->database;
}
/**
* Get the underlying database job.
*
* @return \StdClass
*/
public function getDatabaseJob()
{
return $this->job;
}
}

View File

@@ -1,174 +0,0 @@
<?php namespace Illuminate\Queue\Jobs;
use Illuminate\Queue\IronQueue;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;
class IronJob extends Job implements JobContract {
/**
* The Iron queue instance.
*
* @var \Illuminate\Queue\IronQueue
*/
protected $iron;
/**
* The IronMQ message instance.
*
* @var object
*/
protected $job;
/**
* Indicates if the message was a push message.
*
* @var bool
*/
protected $pushed = false;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Queue\IronQueue $iron
* @param object $job
* @param bool $pushed
* @return void
*/
public function __construct(Container $container,
IronQueue $iron,
$job,
$pushed = false)
{
$this->job = $job;
$this->iron = $iron;
$this->pushed = $pushed;
$this->container = $container;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job->body;
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
if (isset($this->job->pushed)) return;
$this->iron->deleteMessage($this->getQueue(), $this->job->id);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
if ( ! $this->pushed) $this->delete();
$this->recreateJob($delay);
}
/**
* Release a pushed job back onto the queue.
*
* @param int $delay
* @return void
*/
protected function recreateJob($delay)
{
$payload = json_decode($this->job->body, true);
array_set($payload, 'attempts', array_get($payload, 'attempts', 1) + 1);
$this->iron->recreate(json_encode($payload), $this->getQueue(), $delay);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return array_get(json_decode($this->job->body, true), 'attempts', 1);
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job->id;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the underlying Iron queue instance.
*
* @return \Illuminate\Queue\IronQueue
*/
public function getIron()
{
return $this->iron;
}
/**
* Get the underlying IronMQ job.
*
* @return array
*/
public function getIronJob()
{
return $this->job;
}
/**
* Get the name of the queue the job belongs to.
*
* @return string
*/
public function getQueue()
{
return array_get(json_decode($this->job->body, true), 'queue');
}
}

View File

@@ -1,267 +1,293 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use DateTime;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
abstract class Job {
abstract class Job
{
/**
* The job handler instance.
*
* @var mixed
*/
protected $instance;
/**
* The job handler instance.
*
* @var mixed
*/
protected $instance;
/**
* The IoC container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* The IoC container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* The name of the queue the job belongs to.
*
* @var string
*/
protected $queue;
/**
* The name of the queue the job belongs to.
*
* @var string
*/
protected $queue;
/**
* Indicates if the job has been deleted.
*
* @var bool
*/
protected $deleted = false;
/**
* Indicates if the job has been deleted.
*
* @var bool
*/
protected $deleted = false;
/**
* Indicates if the job has been released.
*
* @var bool
*/
protected $released = false;
/**
* Indicates if the job has been released.
*
* @var bool
*/
protected $released = false;
/**
* Fire the job.
*
* @return void
*/
abstract public function fire();
/**
* Fire the job.
*
* @return void
*/
abstract public function fire();
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
$this->deleted = true;
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
$this->deleted = true;
}
/**
* Determine if the job has been deleted.
*
* @return bool
*/
public function isDeleted()
{
return $this->deleted;
}
/**
* Determine if the job has been deleted.
*
* @return bool
*/
public function isDeleted()
{
return $this->deleted;
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
$this->released = true;
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
$this->released = true;
}
/**
* Determine if the job was released back into the queue.
*
* @return bool
*/
public function isReleased()
{
return $this->released;
}
/**
* Determine if the job was released back into the queue.
*
* @return bool
*/
public function isReleased()
{
return $this->released;
}
/**
* Determine if the job has been deleted or released.
*
* @return bool
*/
public function isDeletedOrReleased()
{
return $this->isDeleted() || $this->isReleased();
}
/**
* Determine if the job has been deleted or released.
*
* @return bool
*/
public function isDeletedOrReleased()
{
return $this->isDeleted() || $this->isReleased();
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
abstract public function attempts();
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
abstract public function attempts();
/**
* Get the raw body string for the job.
*
* @return string
*/
abstract public function getRawBody();
/**
* Get the raw body string for the job.
*
* @return string
*/
abstract public function getRawBody();
/**
* Resolve and fire the job handler method.
*
* @param array $payload
* @return void
*/
protected function resolveAndFire(array $payload)
{
list($class, $method) = $this->parseJob($payload['job']);
/**
* Resolve and fire the job handler method.
*
* @param array $payload
* @return void
*/
protected function resolveAndFire(array $payload)
{
list($class, $method) = $this->parseJob($payload['job']);
$this->instance = $this->resolve($class);
$this->instance = $this->resolve($class);
$this->instance->{$method}($this, $this->resolveQueueableEntities($payload['data']));
}
$this->instance->{$method}($this, $this->resolveQueueableEntities($payload['data']));
}
/**
* Parse the job declaration into class and method.
*
* @param string $job
* @return array
*/
protected function parseJob($job)
{
$segments = explode('@', $job);
/**
* Parse the job declaration into class and method.
*
* @param string $job
* @return array
*/
protected function parseJob($job)
{
$segments = explode('@', $job);
return count($segments) > 1 ? $segments : [$segments[0], 'fire'];
}
return count($segments) > 1 ? $segments : array($segments[0], 'fire');
}
/**
* Resolve the given job handler.
*
* @param string $class
* @return mixed
*/
protected function resolve($class)
{
return $this->container->make($class);
}
/**
* Resolve the given job handler.
*
* @param string $class
* @return mixed
*/
protected function resolve($class)
{
return $this->container->make($class);
}
/**
* Resolve all of the queueable entities in the given payload.
*
* @param mixed $data
* @return mixed
*/
protected function resolveQueueableEntities($data)
{
if (is_string($data)) {
return $this->resolveQueueableEntity($data);
}
/**
* Resolve all of the queueable entities in the given payload.
*
* @param mixed $data
* @return mixed
*/
protected function resolveQueueableEntities($data)
{
if (is_string($data))
{
return $this->resolveQueueableEntity($data);
}
if (is_array($data)) {
$data = array_map(function ($d) {
if (is_array($d)) {
return $this->resolveQueueableEntities($d);
}
if (is_array($data))
{
array_walk($data, function(&$d) { $d = $this->resolveQueueableEntity($d); });
}
return $this->resolveQueueableEntity($d);
}, $data);
}
return $data;
}
return $data;
}
/**
* Resolve a single queueable entity from the resolver.
*
* @param mixed $value
* @return \Illuminate\Contracts\Queue\QueueableEntity
*/
protected function resolveQueueableEntity($value)
{
if (is_string($value) && starts_with($value, '::entity::'))
{
list($marker, $type, $id) = explode('|', $value, 3);
/**
* Resolve a single queueable entity from the resolver.
*
* @param mixed $value
* @return \Illuminate\Contracts\Queue\QueueableEntity
*/
protected function resolveQueueableEntity($value)
{
if (is_string($value) && Str::startsWith($value, '::entity::')) {
list($marker, $type, $id) = explode('|', $value, 3);
return $this->getEntityResolver()->resolve($type, $id);
}
return $this->getEntityResolver()->resolve($type, $id);
}
return $value;
}
return $value;
}
/**
* Call the failed method on the job instance.
*
* @return void
*/
public function failed()
{
$payload = json_decode($this->getRawBody(), true);
/**
* Call the failed method on the job instance.
*
* @return void
*/
public function failed()
{
$payload = json_decode($this->getRawBody(), true);
list($class, $method) = $this->parseJob($payload['job']);
list($class, $method) = $this->parseJob($payload['job']);
$this->instance = $this->resolve($class);
$this->instance = $this->resolve($class);
if (method_exists($this->instance, 'failed'))
{
$this->instance->failed($this->resolveQueueableEntities($payload['data']));
}
}
if (method_exists($this->instance, 'failed')) {
$this->instance->failed($this->resolveQueueableEntities($payload['data']));
}
}
/**
* Get an entity resolver instance.
*
* @return \Illuminate\Contracts\Queue\EntityResolver
*/
protected function getEntityResolver()
{
return $this->container->make('Illuminate\Contracts\Queue\EntityResolver');
}
/**
* Get an entity resolver instance.
*
* @return \Illuminate\Contracts\Queue\EntityResolver
*/
protected function getEntityResolver()
{
return $this->container->make('Illuminate\Contracts\Queue\EntityResolver');
}
/**
* Calculate the number of seconds with the given delay.
*
* @param \DateTime|int $delay
* @return int
*/
protected function getSeconds($delay)
{
if ($delay instanceof DateTime)
{
return max(0, $delay->getTimestamp() - $this->getTime());
}
/**
* Calculate the number of seconds with the given delay.
*
* @param \DateTime|int $delay
* @return int
*/
protected function getSeconds($delay)
{
if ($delay instanceof DateTime) {
return max(0, $delay->getTimestamp() - $this->getTime());
}
return (int) $delay;
}
return (int) $delay;
}
/**
* Get the current system time.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Get the current system time.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Get the name of the queued job class.
*
* @return string
*/
public function getName()
{
return json_decode($this->getRawBody(), true)['job'];
}
/**
* Get the name of the queued job class.
*
* @return string
*/
public function getName()
{
return json_decode($this->getRawBody(), true)['job'];
}
/**
* Get the name of the queue the job belongs to.
*
* @return string
*/
public function getQueue()
{
return $this->queue;
}
/**
* Get the resolved name of the queued job class.
*
* @return string
*/
public function resolveName()
{
$name = $this->getName();
$payload = json_decode($this->getRawBody(), true);
if ($name === 'Illuminate\Queue\CallQueuedHandler@call') {
return Arr::get($payload, 'data.commandName', $name);
}
if ($name === 'Illuminate\Events\CallQueuedHandler@call') {
return $payload['data']['class'].'@'.$payload['data']['method'];
}
return $name;
}
/**
* Get the name of the queue the job belongs to.
*
* @return string
*/
public function getQueue()
{
return $this->queue;
}
}

View File

@@ -1,137 +1,139 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use Illuminate\Support\Arr;
use Illuminate\Queue\RedisQueue;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;
class RedisJob extends Job implements JobContract {
class RedisJob extends Job implements JobContract
{
/**
* The Redis queue instance.
*
* @var \Illuminate\Queue\RedisQueue
*/
protected $redis;
/**
* The Redis queue instance.
*
* @var \Illuminate\Queue\RedisQueue
*/
protected $redis;
/**
* The Redis job payload.
*
* @var string
*/
protected $job;
/**
* The Redis job payload.
*
* @var string
*/
protected $job;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Queue\RedisQueue $redis
* @param string $job
* @param string $queue
* @return void
*/
public function __construct(Container $container, RedisQueue $redis, $job, $queue)
{
$this->job = $job;
$this->redis = $redis;
$this->queue = $queue;
$this->container = $container;
}
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Illuminate\Queue\RedisQueue $redis
* @param string $job
* @param string $queue
* @return void
*/
public function __construct(Container $container, RedisQueue $redis, $job, $queue)
{
$this->job = $job;
$this->redis = $redis;
$this->queue = $queue;
$this->container = $container;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job;
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job;
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
$this->redis->deleteReserved($this->queue, $this->job);
}
$this->redis->deleteReserved($this->queue, $this->job);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
$this->delete();
$this->delete();
$this->redis->release($this->queue, $this->job, $delay, $this->attempts() + 1);
}
$this->redis->release($this->queue, $this->job, $delay, $this->attempts() + 1);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return Arr::get(json_decode($this->job, true), 'attempts');
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return array_get(json_decode($this->job, true), 'attempts');
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return Arr::get(json_decode($this->job, true), 'id');
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return array_get(json_decode($this->job, true), 'id');
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the underlying queue driver instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedisQueue()
{
return $this->redis;
}
/**
* Get the underlying Redis job.
*
* @return string
*/
public function getRedisJob()
{
return $this->job;
}
/**
* Get the underlying queue driver instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedisQueue()
{
return $this->redis;
}
/**
* Get the underlying Redis job.
*
* @return string
*/
public function getRedisJob()
{
return $this->job;
}
}

View File

@@ -1,146 +1,147 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use Aws\Sqs\SqsClient;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;
class SqsJob extends Job implements JobContract {
class SqsJob extends Job implements JobContract
{
/**
* The Amazon SQS client instance.
*
* @var \Aws\Sqs\SqsClient
*/
protected $sqs;
/**
* The Amazon SQS client instance.
*
* @var \Aws\Sqs\SqsClient
*/
protected $sqs;
/**
* The Amazon SQS job instance.
*
* @var array
*/
protected $job;
/**
* The Amazon SQS job instance.
*
* @var array
*/
protected $job;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Aws\Sqs\SqsClient $sqs
* @param string $queue
* @param array $job
* @return void
*/
public function __construct(Container $container,
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Aws\Sqs\SqsClient $sqs
* @param string $queue
* @param array $job
* @return void
*/
public function __construct(Container $container,
SqsClient $sqs,
$queue,
array $job)
{
$this->sqs = $sqs;
$this->job = $job;
$this->queue = $queue;
$this->container = $container;
}
{
$this->sqs = $sqs;
$this->job = $job;
$this->queue = $queue;
$this->container = $container;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->getRawBody(), true));
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job['Body'];
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->job['Body'];
}
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
/**
* Delete the job from the queue.
*
* @return void
*/
public function delete()
{
parent::delete();
$this->sqs->deleteMessage(array(
$this->sqs->deleteMessage([
'QueueUrl' => $this->queue, 'ReceiptHandle' => $this->job['ReceiptHandle'],
'QueueUrl' => $this->queue, 'ReceiptHandle' => $this->job['ReceiptHandle'],
));
}
]);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
$this->sqs->changeMessageVisibility([
'QueueUrl' => $this->queue,
'ReceiptHandle' => $this->job['ReceiptHandle'],
'VisibilityTimeout' => $delay,
]);
}
$this->sqs->changeMessageVisibility([
'QueueUrl' => $this->queue,
'ReceiptHandle' => $this->job['ReceiptHandle'],
'VisibilityTimeout' => $delay,
]);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return (int) $this->job['Attributes']['ApproximateReceiveCount'];
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return (int) $this->job['Attributes']['ApproximateReceiveCount'];
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job['MessageId'];
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return $this->job['MessageId'];
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Get the underlying SQS client instance.
*
* @return \Aws\Sqs\SqsClient
*/
public function getSqs()
{
return $this->sqs;
}
/**
* Get the underlying raw SQS job.
*
* @return array
*/
public function getSqsJob()
{
return $this->job;
}
/**
* Get the underlying SQS client instance.
*
* @return \Aws\Sqs\SqsClient
*/
public function getSqs()
{
return $this->sqs;
}
/**
* Get the underlying raw SQS job.
*
* @return array
*/
public function getSqsJob()
{
return $this->job;
}
}

View File

@@ -1,86 +1,87 @@
<?php namespace Illuminate\Queue\Jobs;
<?php
namespace Illuminate\Queue\Jobs;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;
class SyncJob extends Job implements JobContract {
class SyncJob extends Job implements JobContract
{
/**
* The class name of the job.
*
* @var string
*/
protected $job;
/**
* The class name of the job.
*
* @var string
*/
protected $job;
/**
* The queue message data.
*
* @var string
*/
protected $payload;
/**
* The queue message data.
*
* @var string
*/
protected $payload;
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param string $payload
* @return void
*/
public function __construct(Container $container, $payload)
{
$this->payload = $payload;
$this->container = $container;
}
/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param string $payload
* @return void
*/
public function __construct(Container $container, $payload)
{
$this->payload = $payload;
$this->container = $container;
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->payload, true));
}
/**
* Fire the job.
*
* @return void
*/
public function fire()
{
$this->resolveAndFire(json_decode($this->payload, true));
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->payload;
}
/**
* Get the raw body string for the job.
*
* @return string
*/
public function getRawBody()
{
return $this->payload;
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
}
/**
* Release the job back into the queue.
*
* @param int $delay
* @return void
*/
public function release($delay = 0)
{
parent::release($delay);
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return 1;
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return '';
}
/**
* Get the number of times the job has been attempted.
*
* @return int
*/
public function attempts()
{
return 1;
}
/**
* Get the job identifier.
*
* @return string
*/
public function getJobId()
{
return '';
}
}

View File

@@ -1,238 +1,265 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Closure;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessUtils;
use Symfony\Component\Process\PhpExecutableFinder;
class Listener {
class Listener
{
/**
* The command working path.
*
* @var string
*/
protected $commandPath;
/**
* The command working path.
*
* @var string
*/
protected $commandPath;
/**
* The environment the workers should run under.
*
* @var string
*/
protected $environment;
/**
* The environment the workers should run under.
*
* @var string
*/
protected $environment;
/**
* The amount of seconds to wait before polling the queue.
*
* @var int
*/
protected $sleep = 3;
/**
* The amount of seconds to wait before polling the queue.
*
* @var int
*/
protected $sleep = 3;
/**
* The amount of times to try a job before logging it failed.
*
* @var int
*/
protected $maxTries = 0;
/**
* The amount of times to try a job before logging it failed.
*
* @var int
*/
protected $maxTries = 0;
/**
* The queue worker command line.
*
* @var string
*/
protected $workerCommand;
/**
* The queue worker command line.
*
* @var string
*/
protected $workerCommand;
/**
* The output handler callback.
*
* @var \Closure|null
*/
protected $outputHandler;
/**
* The output handler callback.
*
* @var \Closure|null
*/
protected $outputHandler;
/**
* Create a new queue listener.
*
* @param string $commandPath
* @return void
*/
public function __construct($commandPath)
{
$this->commandPath = $commandPath;
$this->workerCommand = $this->buildWorkerCommand();
}
/**
* Create a new queue listener.
*
* @param string $commandPath
* @return void
*/
public function __construct($commandPath)
{
$this->commandPath = $commandPath;
$this->workerCommand = '"'.PHP_BINARY.'" artisan queue:work %s --queue="%s" --delay=%s --memory=%s --sleep=%s --tries=%s';
}
/**
* Build the environment specific worker command.
*
* @return string
*/
protected function buildWorkerCommand()
{
$binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
/**
* Listen to the given queue connection.
*
* @param string $connection
* @param string $queue
* @param string $delay
* @param string $memory
* @param int $timeout
* @return void
*/
public function listen($connection, $queue, $delay, $memory, $timeout = 60)
{
$process = $this->makeProcess($connection, $queue, $delay, $memory, $timeout);
if (defined('HHVM_VERSION')) {
$binary .= ' --php';
}
while (true)
{
$this->runProcess($process, $memory);
}
}
if (defined('ARTISAN_BINARY')) {
$artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY);
} else {
$artisan = 'artisan';
}
/**
* Run the given process.
*
* @param \Symfony\Component\Process\Process $process
* @param int $memory
* @return void
*/
public function runProcess(Process $process, $memory)
{
$process->run(function($type, $line)
{
$this->handleWorkerOutput($type, $line);
});
$command = 'queue:work %s --queue=%s --delay=%s --memory=%s --sleep=%s --tries=%s';
// Once we have run the job we'll go check if the memory limit has been
// exceeded for the script. If it has, we will kill this script so a
// process manager will restart this with a clean slate of memory.
if ($this->memoryExceeded($memory))
{
$this->stop();
}
}
return "{$binary} {$artisan} {$command}";
}
/**
* Create a new Symfony process for the worker.
*
* @param string $connection
* @param string $queue
* @param int $delay
* @param int $memory
* @param int $timeout
* @return \Symfony\Component\Process\Process
*/
public function makeProcess($connection, $queue, $delay, $memory, $timeout)
{
$string = $this->workerCommand;
/**
* Listen to the given queue connection.
*
* @param string $connection
* @param string $queue
* @param string $delay
* @param string $memory
* @param int $timeout
* @return void
*/
public function listen($connection, $queue, $delay, $memory, $timeout = 60)
{
$process = $this->makeProcess($connection, $queue, $delay, $memory, $timeout);
// If the environment is set, we will append it to the command string so the
// workers will run under the specified environment. Otherwise, they will
// just run under the production environment which is not always right.
if (isset($this->environment))
{
$string .= ' --env='.$this->environment;
}
while (true) {
$this->runProcess($process, $memory);
}
}
// Next, we will just format out the worker commands with all of the various
// options available for the command. This will produce the final command
// line that we will pass into a Symfony process object for processing.
$command = sprintf(
$string, $connection, $queue, $delay,
$memory, $this->sleep, $this->maxTries
);
/**
* Run the given process.
*
* @param \Symfony\Component\Process\Process $process
* @param int $memory
* @return void
*/
public function runProcess(Process $process, $memory)
{
$process->run(function ($type, $line) {
$this->handleWorkerOutput($type, $line);
});
return new Process($command, $this->commandPath, null, null, $timeout);
}
// Once we have run the job we'll go check if the memory limit has been
// exceeded for the script. If it has, we will kill this script so a
// process manager will restart this with a clean slate of memory.
if ($this->memoryExceeded($memory)) {
$this->stop();
}
}
/**
* Handle output from the worker process.
*
* @param int $type
* @param string $line
* @return void
*/
protected function handleWorkerOutput($type, $line)
{
if (isset($this->outputHandler))
{
call_user_func($this->outputHandler, $type, $line);
}
}
/**
* Create a new Symfony process for the worker.
*
* @param string $connection
* @param string $queue
* @param int $delay
* @param int $memory
* @param int $timeout
* @return \Symfony\Component\Process\Process
*/
public function makeProcess($connection, $queue, $delay, $memory, $timeout)
{
$string = $this->workerCommand;
/**
* Determine if the memory limit has been exceeded.
*
* @param int $memoryLimit
* @return bool
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
}
// If the environment is set, we will append it to the command string so the
// workers will run under the specified environment. Otherwise, they will
// just run under the production environment which is not always right.
if (isset($this->environment)) {
$string .= ' --env='.ProcessUtils::escapeArgument($this->environment);
}
/**
* Stop listening and bail out of the script.
*
* @return void
*/
public function stop()
{
die;
}
// Next, we will just format out the worker commands with all of the various
// options available for the command. This will produce the final command
// line that we will pass into a Symfony process object for processing.
$command = sprintf(
$string,
ProcessUtils::escapeArgument($connection),
ProcessUtils::escapeArgument($queue),
$delay,
$memory,
$this->sleep,
$this->maxTries
);
/**
* Set the output handler callback.
*
* @param \Closure $outputHandler
* @return void
*/
public function setOutputHandler(Closure $outputHandler)
{
$this->outputHandler = $outputHandler;
}
return new Process($command, $this->commandPath, null, null, $timeout);
}
/**
* Get the current listener environment.
*
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* Handle output from the worker process.
*
* @param int $type
* @param string $line
* @return void
*/
protected function handleWorkerOutput($type, $line)
{
if (isset($this->outputHandler)) {
call_user_func($this->outputHandler, $type, $line);
}
}
/**
* Set the current environment.
*
* @param string $environment
* @return void
*/
public function setEnvironment($environment)
{
$this->environment = $environment;
}
/**
* Determine if the memory limit has been exceeded.
*
* @param int $memoryLimit
* @return bool
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
}
/**
* Get the amount of seconds to wait before polling the queue.
*
* @return int
*/
public function getSleep()
{
return $this->sleep;
}
/**
* Stop listening and bail out of the script.
*
* @return void
*/
public function stop()
{
die;
}
/**
* Set the amount of seconds to wait before polling the queue.
*
* @param int $sleep
* @return void
*/
public function setSleep($sleep)
{
$this->sleep = $sleep;
}
/**
* Set the output handler callback.
*
* @param \Closure $outputHandler
* @return void
*/
public function setOutputHandler(Closure $outputHandler)
{
$this->outputHandler = $outputHandler;
}
/**
* Set the amount of times to try a job before logging it failed.
*
* @param int $tries
* @return void
*/
public function setMaxTries($tries)
{
$this->maxTries = $tries;
}
/**
* Get the current listener environment.
*
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* Set the current environment.
*
* @param string $environment
* @return void
*/
public function setEnvironment($environment)
{
$this->environment = $environment;
}
/**
* Get the amount of seconds to wait before polling the queue.
*
* @return int
*/
public function getSleep()
{
return $this->sleep;
}
/**
* Set the amount of seconds to wait before polling the queue.
*
* @param int $sleep
* @return void
*/
public function setSleep($sleep)
{
$this->sleep = $sleep;
}
/**
* Set the amount of times to try a job before logging it failed.
*
* @param int $tries
* @return void
*/
public function setMaxTries($tries)
{
$this->maxTries = $tries;
}
}

View File

@@ -1,58 +1,59 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class NullQueue extends Queue implements QueueContract {
class NullQueue extends Queue implements QueueContract
{
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
//
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
//
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
//
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
//
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
//
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
//
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
//
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
//
}
}

View File

@@ -1,224 +1,213 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Closure;
use DateTime;
use RuntimeException;
use Illuminate\Support\Arr;
use SuperClosure\Serializer;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\QueueableEntity;
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
abstract class Queue {
abstract class Queue
{
/**
* The IoC container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* The IoC container instance.
*
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* Push a new job onto the queue.
*
* @param string $queue
* @param string $job
* @param mixed $data
* @return mixed
*/
public function pushOn($queue, $job, $data = '')
{
return $this->push($job, $data, $queue);
}
/**
* Push a new job onto the queue.
*
* @param string $queue
* @param string $job
* @param mixed $data
* @return mixed
*/
public function pushOn($queue, $job, $data = '')
{
return $this->push($job, $data, $queue);
}
/**
* Push a new job onto the queue after a delay.
*
* @param string $queue
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @return mixed
*/
public function laterOn($queue, $delay, $job, $data = '')
{
return $this->later($delay, $job, $data, $queue);
}
/**
* Push a new job onto the queue after a delay.
*
* @param string $queue
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @return mixed
*/
public function laterOn($queue, $delay, $job, $data = '')
{
return $this->later($delay, $job, $data, $queue);
}
/**
* Push an array of jobs onto the queue.
*
* @param array $jobs
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function bulk($jobs, $data = '', $queue = null)
{
foreach ((array) $jobs as $job) {
$this->push($job, $data, $queue);
}
}
/**
* Marshal a push queue request and fire the job.
*
* @throws \RuntimeException
*/
public function marshal()
{
throw new RuntimeException("Push queues only supported by Iron.");
}
/**
* Create a payload string from the given job and data.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return string
*/
protected function createPayload($job, $data = '', $queue = null)
{
if ($job instanceof Closure) {
return json_encode($this->createClosurePayload($job, $data));
} elseif (is_object($job)) {
return json_encode([
'job' => 'Illuminate\Queue\CallQueuedHandler@call',
'data' => ['commandName' => get_class($job), 'command' => serialize(clone $job)],
]);
}
/**
* Push an array of jobs onto the queue.
*
* @param array $jobs
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function bulk($jobs, $data = '', $queue = null)
{
foreach ((array) $jobs as $job)
{
$this->push($job, $data, $queue);
}
}
return json_encode($this->createPlainPayload($job, $data));
}
/**
* Create a payload string from the given job and data.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return string
*/
protected function createPayload($job, $data = '', $queue = null)
{
if ($job instanceof Closure)
{
return json_encode($this->createClosurePayload($job, $data));
}
elseif (is_object($job))
{
return json_encode([
'job' => 'Illuminate\Queue\CallQueuedHandler@call',
'data' => ['command' => serialize(clone $job)],
]);
}
/**
* Create a typical, "plain" queue payload array.
*
* @param string $job
* @param mixed $data
* @return array
*/
protected function createPlainPayload($job, $data)
{
return ['job' => $job, 'data' => $this->prepareQueueableEntities($data)];
}
return json_encode($this->createPlainPayload($job, $data));
}
/**
* Prepare any queueable entities for storage in the queue.
*
* @param mixed $data
* @return mixed
*/
protected function prepareQueueableEntities($data)
{
if ($data instanceof QueueableEntity) {
return $this->prepareQueueableEntity($data);
}
/**
* Create a typical, "plain" queue payload array.
*
* @param string $job
* @param mixed $data
* @return array
*/
protected function createPlainPayload($job, $data)
{
return ['job' => $job, 'data' => $this->prepareQueueableEntities($data)];
}
if (is_array($data)) {
$data = array_map(function ($d) {
if (is_array($d)) {
return $this->prepareQueueableEntities($d);
}
/**
* Prepare any queueable entities for storage in the queue.
*
* @param mixed $data
* @return mixed
*/
protected function prepareQueueableEntities($data)
{
if ($data instanceof QueueableEntity)
{
return $this->prepareQueueableEntity($data);
}
return $this->prepareQueueableEntity($d);
}, $data);
}
if (is_array($data))
{
array_walk($data, function(&$d) { $d = $this->prepareQueueableEntity($d); });
}
return $data;
}
return $data;
}
/**
* Prepare a single queueable entity for storage on the queue.
*
* @param mixed $value
* @return mixed
*/
protected function prepareQueueableEntity($value)
{
if ($value instanceof QueueableEntity) {
return '::entity::|'.get_class($value).'|'.$value->getQueueableId();
}
/**
* Prepare a single queueable entity for storage on the queue.
*
* @param mixed $value
* @return mixed
*/
protected function prepareQueueableEntity($value)
{
if ($value instanceof QueueableEntity)
{
return '::entity::|'.get_class($value).'|'.$value->getQueueableId();
}
return $value;
}
return $value;
}
/**
* Create a payload string for the given Closure job.
*
* @param \Closure $job
* @param mixed $data
* @return array
*/
protected function createClosurePayload($job, $data)
{
$closure = $this->crypt->encrypt((new Serializer)->serialize($job));
/**
* Create a payload string for the given Closure job.
*
* @param \Closure $job
* @param mixed $data
* @return string
*/
protected function createClosurePayload($job, $data)
{
$closure = $this->crypt->encrypt((new Serializer)->serialize($job));
return ['job' => 'IlluminateQueueClosure', 'data' => compact('closure')];
}
return ['job' => 'IlluminateQueueClosure', 'data' => compact('closure')];
}
/**
* Set additional meta on a payload string.
*
* @param string $payload
* @param string $key
* @param string $value
* @return string
*/
protected function setMeta($payload, $key, $value)
{
$payload = json_decode($payload, true);
/**
* Set additional meta on a payload string.
*
* @param string $payload
* @param string $key
* @param string $value
* @return string
*/
protected function setMeta($payload, $key, $value)
{
$payload = json_decode($payload, true);
return json_encode(Arr::set($payload, $key, $value));
}
return json_encode(array_set($payload, $key, $value));
}
/**
* Calculate the number of seconds with the given delay.
*
* @param \DateTime|int $delay
* @return int
*/
protected function getSeconds($delay)
{
if ($delay instanceof DateTime) {
return max(0, $delay->getTimestamp() - $this->getTime());
}
/**
* Calculate the number of seconds with the given delay.
*
* @param \DateTime|int $delay
* @return int
*/
protected function getSeconds($delay)
{
if ($delay instanceof DateTime)
{
return max(0, $delay->getTimestamp() - $this->getTime());
}
return (int) $delay;
}
return (int) $delay;
}
/**
* Get the current UNIX timestamp.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Get the current UNIX timestamp.
*
* @return int
*/
protected function getTime()
{
return time();
}
/**
* Set the IoC container instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Set the encrypter instance.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $crypt
* @return void
*/
public function setEncrypter(EncrypterContract $crypt)
{
$this->crypt = $crypt;
}
/**
* Set the IoC container instance.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Set the encrypter instance.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $crypt
* @return void
*/
public function setEncrypter(EncrypterContract $crypt)
{
$this->crypt = $crypt;
}
}

View File

@@ -1,226 +1,269 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Closure;
use InvalidArgumentException;
use Illuminate\Contracts\Queue\Factory as FactoryContract;
use Illuminate\Contracts\Queue\Monitor as MonitorContract;
class QueueManager implements FactoryContract, MonitorContract {
class QueueManager implements FactoryContract, MonitorContract
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The array of resolved queue connections.
*
* @var array
*/
protected $connections = [];
/**
* The array of resolved queue connections.
*
* @var array
*/
protected $connections = array();
/**
* The array of resolved queue connectors.
*
* @var array
*/
protected $connectors = [];
/**
* Create a new queue manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Create a new queue manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Register an event listener for the daemon queue loop.
*
* @param mixed $callback
* @return void
*/
public function looping($callback)
{
$this->app['events']->listen('illuminate.queue.looping', $callback);
}
/**
* Register an event listener for the before job event.
*
* @param mixed $callback
* @return void
*/
public function before($callback)
{
$this->app['events']->listen(Events\JobProcessing::class, $callback);
}
/**
* Register an event listener for the failed job event.
*
* @param mixed $callback
* @return void
*/
public function failing($callback)
{
$this->app['events']->listen('illuminate.queue.failed', $callback);
}
/**
* Register an event listener for the after job event.
*
* @param mixed $callback
* @return void
*/
public function after($callback)
{
$this->app['events']->listen(Events\JobProcessed::class, $callback);
}
/**
* Register an event listener for the daemon queue stopping.
*
* @param mixed $callback
* @return void
*/
public function stopping($callback)
{
$this->app['events']->listen('illuminate.queue.stopping', $callback);
}
/**
* Register an event listener for the exception occurred job event.
*
* @param mixed $callback
* @return void
*/
public function exceptionOccurred($callback)
{
$this->app['events']->listen(Events\JobExceptionOccurred::class, $callback);
}
/**
* Determine if the driver is connected.
*
* @param string $name
* @return bool
*/
public function connected($name = null)
{
return isset($this->connections[$name ?: $this->getDefaultDriver()]);
}
/**
* Register an event listener for the daemon queue loop.
*
* @param mixed $callback
* @return void
*/
public function looping($callback)
{
$this->app['events']->listen('illuminate.queue.looping', $callback);
}
/**
* Resolve a queue connection instance.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connection($name = null)
{
$name = $name ?: $this->getDefaultDriver();
/**
* Register an event listener for the failed job event.
*
* @param mixed $callback
* @return void
*/
public function failing($callback)
{
$this->app['events']->listen(Events\JobFailed::class, $callback);
}
// If the connection has not been resolved yet we will resolve it now as all
// of the connections are resolved when they are actually needed so we do
// not make any unnecessary connection to the various queue end-points.
if ( ! isset($this->connections[$name]))
{
$this->connections[$name] = $this->resolve($name);
/**
* Register an event listener for the daemon queue stopping.
*
* @param mixed $callback
* @return void
*/
public function stopping($callback)
{
$this->app['events']->listen(Events\WorkerStopping::class, $callback);
}
$this->connections[$name]->setContainer($this->app);
/**
* Determine if the driver is connected.
*
* @param string $name
* @return bool
*/
public function connected($name = null)
{
return isset($this->connections[$name ?: $this->getDefaultDriver()]);
}
$this->connections[$name]->setEncrypter($this->app['encrypter']);
}
/**
* Resolve a queue connection instance.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connection($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->connections[$name];
}
// If the connection has not been resolved yet we will resolve it now as all
// of the connections are resolved when they are actually needed so we do
// not make any unnecessary connection to the various queue end-points.
if (! isset($this->connections[$name])) {
$this->connections[$name] = $this->resolve($name);
/**
* Resolve a queue connection.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
$this->connections[$name]->setContainer($this->app);
return $this->getConnector($config['driver'])->connect($config);
}
$this->connections[$name]->setEncrypter($this->app['encrypter']);
}
/**
* Get the connector for a given driver.
*
* @param string $driver
* @return \Illuminate\Queue\Connectors\ConnectorInterface
*
* @throws \InvalidArgumentException
*/
protected function getConnector($driver)
{
if (isset($this->connectors[$driver]))
{
return call_user_func($this->connectors[$driver]);
}
return $this->connections[$name];
}
throw new InvalidArgumentException("No connector for [$driver]");
}
/**
* Resolve a queue connection.
*
* @param string $name
* @return \Illuminate\Contracts\Queue\Queue
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
/**
* Add a queue connection resolver.
*
* @param string $driver
* @param \Closure $resolver
* @return void
*/
public function extend($driver, Closure $resolver)
{
return $this->addConnector($driver, $resolver);
}
return $this->getConnector($config['driver'])->connect($config);
}
/**
* Add a queue connection resolver.
*
* @param string $driver
* @param \Closure $resolver
* @return void
*/
public function addConnector($driver, Closure $resolver)
{
$this->connectors[$driver] = $resolver;
}
/**
* Get the connector for a given driver.
*
* @param string $driver
* @return \Illuminate\Queue\Connectors\ConnectorInterface
*
* @throws \InvalidArgumentException
*/
protected function getConnector($driver)
{
if (isset($this->connectors[$driver])) {
return call_user_func($this->connectors[$driver]);
}
/**
* Get the queue connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["queue.connections.{$name}"];
}
throw new InvalidArgumentException("No connector for [$driver]");
}
/**
* Get the name of the default queue connection.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['queue.default'];
}
/**
* Add a queue connection resolver.
*
* @param string $driver
* @param \Closure $resolver
* @return void
*/
public function extend($driver, Closure $resolver)
{
return $this->addConnector($driver, $resolver);
}
/**
* Set the name of the default queue connection.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['queue.default'] = $name;
}
/**
* Add a queue connection resolver.
*
* @param string $driver
* @param \Closure $resolver
* @return void
*/
public function addConnector($driver, Closure $resolver)
{
$this->connectors[$driver] = $resolver;
}
/**
* Get the full name for the given connection.
*
* @param string $connection
* @return string
*/
public function getName($connection = null)
{
return $connection ?: $this->getDefaultDriver();
}
/**
* Get the queue connection configuration.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
if ($name === null || $name === 'null') {
return ['driver' => 'null'];
}
/**
* Determine if the application is in maintenance mode.
*
* @return bool
*/
public function isDownForMaintenance()
{
return $this->app->isDownForMaintenance();
}
return $this->app['config']["queue.connections.{$name}"];
}
/**
* Dynamically pass calls to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
$callable = array($this->connection(), $method);
/**
* Get the name of the default queue connection.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['queue.default'];
}
return call_user_func_array($callable, $parameters);
}
/**
* Set the name of the default queue connection.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['queue.default'] = $name;
}
/**
* Get the full name for the given connection.
*
* @param string $connection
* @return string
*/
public function getName($connection = null)
{
return $connection ?: $this->getDefaultDriver();
}
/**
* Determine if the application is in maintenance mode.
*
* @return bool
*/
public function isDownForMaintenance()
{
return $this->app->isDownForMaintenance();
}
/**
* Dynamically pass calls to the default connection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
$callable = [$this->connection(), $method];
return call_user_func_array($callable, $parameters);
}
}

View File

@@ -1,4 +1,6 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use IlluminateQueueClosure;
use Illuminate\Support\ServiceProvider;
@@ -6,335 +8,270 @@ use Illuminate\Queue\Console\WorkCommand;
use Illuminate\Queue\Console\ListenCommand;
use Illuminate\Queue\Console\RestartCommand;
use Illuminate\Queue\Connectors\SqsConnector;
use Illuminate\Queue\Console\SubscribeCommand;
use Illuminate\Queue\Connectors\NullConnector;
use Illuminate\Queue\Connectors\SyncConnector;
use Illuminate\Queue\Connectors\IronConnector;
use Illuminate\Queue\Connectors\RedisConnector;
use Illuminate\Queue\Failed\NullFailedJobProvider;
use Illuminate\Queue\Connectors\DatabaseConnector;
use Illuminate\Queue\Connectors\BeanstalkdConnector;
use Illuminate\Queue\Failed\DatabaseFailedJobProvider;
class QueueServiceProvider extends ServiceProvider {
class QueueServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerManager();
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerManager();
$this->registerWorker();
$this->registerWorker();
$this->registerListener();
$this->registerListener();
$this->registerFailedJobServices();
$this->registerSubscriber();
$this->registerQueueClosure();
}
$this->registerFailedJobServices();
/**
* Register the queue manager.
*
* @return void
*/
protected function registerManager()
{
$this->app->singleton('queue', function ($app) {
// Once we have an instance of the queue manager, we will register the various
// resolvers for the queue connectors. These connectors are responsible for
// creating the classes that accept queue configs and instantiate queues.
$manager = new QueueManager($app);
$this->registerQueueClosure();
}
$this->registerConnectors($manager);
/**
* Register the queue manager.
*
* @return void
*/
protected function registerManager()
{
$this->app->singleton('queue', function($app)
{
// Once we have an instance of the queue manager, we will register the various
// resolvers for the queue connectors. These connectors are responsible for
// creating the classes that accept queue configs and instantiate queues.
$manager = new QueueManager($app);
return $manager;
});
$this->registerConnectors($manager);
$this->app->singleton('queue.connection', function ($app) {
return $app['queue']->connection();
});
}
return $manager;
});
/**
* Register the queue worker.
*
* @return void
*/
protected function registerWorker()
{
$this->registerWorkCommand();
$this->app->singleton('queue.connection', function($app)
{
return $app['queue']->connection();
});
}
$this->registerRestartCommand();
/**
* Register the queue worker.
*
* @return void
*/
protected function registerWorker()
{
$this->registerWorkCommand();
$this->app->singleton('queue.worker', function ($app) {
return new Worker($app['queue'], $app['queue.failer'], $app['events']);
});
}
$this->registerRestartCommand();
/**
* Register the queue worker console command.
*
* @return void
*/
protected function registerWorkCommand()
{
$this->app->singleton('command.queue.work', function ($app) {
return new WorkCommand($app['queue.worker']);
});
$this->app->singleton('queue.worker', function($app)
{
return new Worker($app['queue'], $app['queue.failer'], $app['events']);
});
}
$this->commands('command.queue.work');
}
/**
* Register the queue worker console command.
*
* @return void
*/
protected function registerWorkCommand()
{
$this->app->singleton('command.queue.work', function($app)
{
return new WorkCommand($app['queue.worker']);
});
/**
* Register the queue listener.
*
* @return void
*/
protected function registerListener()
{
$this->registerListenCommand();
$this->commands('command.queue.work');
}
$this->app->singleton('queue.listener', function ($app) {
return new Listener($app->basePath());
});
}
/**
* Register the queue listener.
*
* @return void
*/
protected function registerListener()
{
$this->registerListenCommand();
/**
* Register the queue listener console command.
*
* @return void
*/
protected function registerListenCommand()
{
$this->app->singleton('command.queue.listen', function ($app) {
return new ListenCommand($app['queue.listener']);
});
$this->app->singleton('queue.listener', function($app)
{
return new Listener($app->basePath());
});
}
$this->commands('command.queue.listen');
}
/**
* Register the queue listener console command.
*
* @return void
*/
protected function registerListenCommand()
{
$this->app->singleton('command.queue.listen', function($app)
{
return new ListenCommand($app['queue.listener']);
});
/**
* Register the queue restart console command.
*
* @return void
*/
public function registerRestartCommand()
{
$this->app->singleton('command.queue.restart', function () {
return new RestartCommand;
});
$this->commands('command.queue.listen');
}
$this->commands('command.queue.restart');
}
/**
* Register the queue restart console command.
*
* @return void
*/
public function registerRestartCommand()
{
$this->app->singleton('command.queue.restart', function()
{
return new RestartCommand;
});
/**
* Register the connectors on the queue manager.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
public function registerConnectors($manager)
{
foreach (['Null', 'Sync', 'Database', 'Beanstalkd', 'Redis', 'Sqs'] as $connector) {
$this->{"register{$connector}Connector"}($manager);
}
}
$this->commands('command.queue.restart');
}
/**
* Register the Null queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerNullConnector($manager)
{
$manager->addConnector('null', function () {
return new NullConnector;
});
}
/**
* Register the push queue subscribe command.
*
* @return void
*/
protected function registerSubscriber()
{
$this->app->singleton('command.queue.subscribe', function()
{
return new SubscribeCommand;
});
/**
* Register the Sync queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerSyncConnector($manager)
{
$manager->addConnector('sync', function () {
return new SyncConnector;
});
}
$this->commands('command.queue.subscribe');
}
/**
* Register the Beanstalkd queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerBeanstalkdConnector($manager)
{
$manager->addConnector('beanstalkd', function () {
return new BeanstalkdConnector;
});
}
/**
* Register the connectors on the queue manager.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
public function registerConnectors($manager)
{
foreach (array('Null', 'Sync', 'Database', 'Beanstalkd', 'Redis', 'Sqs', 'Iron') as $connector)
{
$this->{"register{$connector}Connector"}($manager);
}
}
/**
* Register the database queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerDatabaseConnector($manager)
{
$manager->addConnector('database', function () {
return new DatabaseConnector($this->app['db']);
});
}
/**
* Register the Null queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerNullConnector($manager)
{
$manager->addConnector('null', function()
{
return new NullConnector;
});
}
/**
* Register the Redis queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerRedisConnector($manager)
{
$app = $this->app;
/**
* Register the Sync queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerSyncConnector($manager)
{
$manager->addConnector('sync', function()
{
return new SyncConnector;
});
}
$manager->addConnector('redis', function () use ($app) {
return new RedisConnector($app['redis']);
});
}
/**
* Register the Beanstalkd queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerBeanstalkdConnector($manager)
{
$manager->addConnector('beanstalkd', function()
{
return new BeanstalkdConnector;
});
}
/**
* Register the Amazon SQS queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerSqsConnector($manager)
{
$manager->addConnector('sqs', function () {
return new SqsConnector;
});
}
/**
* Register the database queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerDatabaseConnector($manager)
{
$manager->addConnector('database', function()
{
return new DatabaseConnector($this->app['db']);
});
}
/**
* Register the failed job services.
*
* @return void
*/
protected function registerFailedJobServices()
{
$this->app->singleton('queue.failer', function ($app) {
$config = $app['config']['queue.failed'];
/**
* Register the Redis queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerRedisConnector($manager)
{
$app = $this->app;
if (isset($config['table'])) {
return new DatabaseFailedJobProvider($app['db'], $config['database'], $config['table']);
} else {
return new NullFailedJobProvider;
}
});
}
$manager->addConnector('redis', function() use ($app)
{
return new RedisConnector($app['redis']);
});
}
/**
* Register the Amazon SQS queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerSqsConnector($manager)
{
$manager->addConnector('sqs', function()
{
return new SqsConnector;
});
}
/**
* Register the IronMQ queue connector.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
protected function registerIronConnector($manager)
{
$app = $this->app;
$manager->addConnector('iron', function() use ($app)
{
return new IronConnector($app['encrypter'], $app['request']);
});
$this->registerIronRequestBinder();
}
/**
* Register the request rebinding event for the Iron queue.
*
* @return void
*/
protected function registerIronRequestBinder()
{
$this->app->rebinding('request', function($app, $request)
{
if ($app['queue']->connected('iron'))
{
$app['queue']->connection('iron')->setRequest($request);
}
});
}
/**
* Register the failed job services.
*
* @return void
*/
protected function registerFailedJobServices()
{
$this->app->singleton('queue.failer', function($app)
{
$config = $app['config']['queue.failed'];
return new DatabaseFailedJobProvider($app['db'], $config['database'], $config['table']);
});
}
/**
* Register the Illuminate queued closure job.
*
* @return void
*/
protected function registerQueueClosure()
{
$this->app->singleton('IlluminateQueueClosure', function($app)
{
return new IlluminateQueueClosure($app['encrypter']);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array(
'queue', 'queue.worker', 'queue.listener', 'queue.failer',
'command.queue.work', 'command.queue.listen', 'command.queue.restart',
'command.queue.subscribe', 'queue.connection',
);
}
/**
* Register the Illuminate queued closure job.
*
* @return void
*/
protected function registerQueueClosure()
{
$this->app->singleton('IlluminateQueueClosure', function ($app) {
return new IlluminateQueueClosure($app['encrypter']);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'queue', 'queue.worker', 'queue.listener', 'queue.failer',
'command.queue.work', 'command.queue.listen',
'command.queue.restart', 'queue.connection',
];
}
}

View File

@@ -1,320 +1,319 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Redis\Database;
use Illuminate\Queue\Jobs\RedisJob;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class RedisQueue extends Queue implements QueueContract {
class RedisQueue extends Queue implements QueueContract
{
/**
* The Redis database instance.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* The Redis database instance.
*
* @var \Illuminate\Redis\Database
*/
protected $redis;
/**
* The connection name.
*
* @var string
*/
protected $connection;
/**
* The connection name.
*
* @var string
*/
protected $connection;
/**
* The name of the default queue.
*
* @var string
*/
protected $default;
/**
* The name of the default queue.
*
* @var string
*/
protected $default;
/**
* The expiration time of a job.
*
* @var int|null
*/
protected $expire = 60;
/**
* The expiration time of a job.
*
* @var int|null
*/
protected $expire = 60;
/**
* Create a new Redis queue instance.
*
* @param \Illuminate\Redis\Database $redis
* @param string $default
* @param string $connection
* @return void
*/
public function __construct(Database $redis, $default = 'default', $connection = null)
{
$this->redis = $redis;
$this->default = $default;
$this->connection = $connection;
}
/**
* Create a new Redis queue instance.
*
* @param \Illuminate\Redis\Database $redis
* @param string $default
* @param string $connection
* @return void
*/
public function __construct(Database $redis, $default = 'default', $connection = null)
{
$this->redis = $redis;
$this->default = $default;
$this->connection = $connection;
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return void
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
$this->getConnection()->rpush($this->getQueue($queue), $payload);
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
$this->getConnection()->rpush($this->getQueue($queue), $payload);
return Arr::get(json_decode($payload, true), 'id');
}
return array_get(json_decode($payload, true), 'id');
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return void
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
$delay = $this->getSeconds($delay);
$delay = $this->getSeconds($delay);
$this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload);
$this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload);
return Arr::get(json_decode($payload, true), 'id');
}
return array_get(json_decode($payload, true), 'id');
}
/**
* Release a reserved job back onto the queue.
*
* @param string $queue
* @param string $payload
* @param int $delay
* @param int $attempts
* @return void
*/
public function release($queue, $payload, $delay, $attempts)
{
$payload = $this->setMeta($payload, 'attempts', $attempts);
/**
* Release a reserved job back onto the queue.
*
* @param string $queue
* @param string $payload
* @param int $delay
* @param int $attempts
* @return void
*/
public function release($queue, $payload, $delay, $attempts)
{
$payload = $this->setMeta($payload, 'attempts', $attempts);
$this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload);
}
$this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload);
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$original = $queue ?: $this->default;
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$original = $queue ?: $this->default;
$queue = $this->getQueue($queue);
$queue = $this->getQueue($queue);
if (! is_null($this->expire)) {
$this->migrateAllExpiredJobs($queue);
}
if ( ! is_null($this->expire))
{
$this->migrateAllExpiredJobs($queue);
}
$job = $this->getConnection()->lpop($queue);
$job = $this->getConnection()->lpop($queue);
if (! is_null($job)) {
$this->getConnection()->zadd($queue.':reserved', $this->getTime() + $this->expire, $job);
if ( ! is_null($job))
{
$this->getConnection()->zadd($queue.':reserved', $this->getTime() + $this->expire, $job);
return new RedisJob($this->container, $this, $job, $original);
}
}
return new RedisJob($this->container, $this, $job, $original);
}
}
/**
* Delete a reserved job from the queue.
*
* @param string $queue
* @param string $job
* @return void
*/
public function deleteReserved($queue, $job)
{
$this->getConnection()->zrem($this->getQueue($queue).':reserved', $job);
}
/**
* Delete a reserved job from the queue.
*
* @param string $queue
* @param string $job
* @return void
*/
public function deleteReserved($queue, $job)
{
$this->getConnection()->zrem($this->getQueue($queue).':reserved', $job);
}
/**
* Migrate all of the waiting jobs in the queue.
*
* @param string $queue
* @return void
*/
protected function migrateAllExpiredJobs($queue)
{
$this->migrateExpiredJobs($queue.':delayed', $queue);
/**
* Migrate all of the waiting jobs in the queue.
*
* @param string $queue
* @return void
*/
protected function migrateAllExpiredJobs($queue)
{
$this->migrateExpiredJobs($queue.':delayed', $queue);
$this->migrateExpiredJobs($queue.':reserved', $queue);
}
$this->migrateExpiredJobs($queue.':reserved', $queue);
}
/**
* Migrate the delayed jobs that are ready to the regular queue.
*
* @param string $from
* @param string $to
* @return void
*/
public function migrateExpiredJobs($from, $to)
{
$options = ['cas' => true, 'watch' => $from, 'retry' => 10];
/**
* Migrate the delayed jobs that are ready to the regular queue.
*
* @param string $from
* @param string $to
* @return void
*/
public function migrateExpiredJobs($from, $to)
{
$options = ['cas' => true, 'watch' => $from, 'retry' => 10];
$this->getConnection()->transaction($options, function ($transaction) use ($from, $to) {
// First we need to get all of jobs that have expired based on the current time
// so that we can push them onto the main queue. After we get them we simply
// remove them from this "delay" queues. All of this within a transaction.
$jobs = $this->getExpiredJobs(
$transaction, $from, $time = $this->getTime()
);
$this->getConnection()->transaction($options, function ($transaction) use ($from, $to)
{
// First we need to get all of jobs that have expired based on the current time
// so that we can push them onto the main queue. After we get them we simply
// remove them from this "delay" queues. All of this within a transaction.
$jobs = $this->getExpiredJobs(
$transaction, $from, $time = $this->getTime()
);
// If we actually found any jobs, we will remove them from the old queue and we
// will insert them onto the new (ready) "queue". This means they will stand
// ready to be processed by the queue worker whenever their turn comes up.
if (count($jobs) > 0) {
$this->removeExpiredJobs($transaction, $from, $time);
// If we actually found any jobs, we will remove them from the old queue and we
// will insert them onto the new (ready) "queue". This means they will stand
// ready to be processed by the queue worker whenever their turn comes up.
if (count($jobs) > 0)
{
$this->removeExpiredJobs($transaction, $from, $time);
$this->pushExpiredJobsOntoNewQueue($transaction, $to, $jobs);
}
});
}
$this->pushExpiredJobsOntoNewQueue($transaction, $to, $jobs);
}
});
}
/**
* Get the expired jobs from a given queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $from
* @param int $time
* @return array
*/
protected function getExpiredJobs($transaction, $from, $time)
{
return $transaction->zrangebyscore($from, '-inf', $time);
}
/**
* Get the expired jobs from a given queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $from
* @param int $time
* @return array
*/
protected function getExpiredJobs($transaction, $from, $time)
{
return $transaction->zrangebyscore($from, '-inf', $time);
}
/**
* Remove the expired jobs from a given queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $from
* @param int $time
* @return void
*/
protected function removeExpiredJobs($transaction, $from, $time)
{
$transaction->multi();
/**
* Remove the expired jobs from a given queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $from
* @param int $time
* @return void
*/
protected function removeExpiredJobs($transaction, $from, $time)
{
$transaction->multi();
$transaction->zremrangebyscore($from, '-inf', $time);
}
$transaction->zremrangebyscore($from, '-inf', $time);
}
/**
* Push all of the given jobs onto another queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $to
* @param array $jobs
* @return void
*/
protected function pushExpiredJobsOntoNewQueue($transaction, $to, $jobs)
{
call_user_func_array([$transaction, 'rpush'], array_merge([$to], $jobs));
}
/**
* Push all of the given jobs onto another queue.
*
* @param \Predis\Transaction\MultiExec $transaction
* @param string $to
* @param array $jobs
* @return void
*/
protected function pushExpiredJobsOntoNewQueue($transaction, $to, $jobs)
{
call_user_func_array([$transaction, 'rpush'], array_merge([$to], $jobs));
}
/**
* Create a payload string from the given job and data.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return string
*/
protected function createPayload($job, $data = '', $queue = null)
{
$payload = parent::createPayload($job, $data);
/**
* Create a payload string from the given job and data.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return string
*/
protected function createPayload($job, $data = '', $queue = null)
{
$payload = parent::createPayload($job, $data);
$payload = $this->setMeta($payload, 'id', $this->getRandomId());
$payload = $this->setMeta($payload, 'id', $this->getRandomId());
return $this->setMeta($payload, 'attempts', 1);
}
return $this->setMeta($payload, 'attempts', 1);
}
/**
* Get a random ID string.
*
* @return string
*/
protected function getRandomId()
{
return Str::random(32);
}
/**
* Get a random ID string.
*
* @return string
*/
protected function getRandomId()
{
return str_random(32);
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
protected function getQueue($queue)
{
return 'queues:'.($queue ?: $this->default);
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
protected function getQueue($queue)
{
return 'queues:'.($queue ?: $this->default);
}
/**
* Get the connection for the queue.
*
* @return \Predis\ClientInterface
*/
protected function getConnection()
{
return $this->redis->connection($this->connection);
}
/**
* Get the connection for the queue.
*
* @return \Predis\ClientInterface
*/
protected function getConnection()
{
return $this->redis->connection($this->connection);
}
/**
* Get the underlying Redis instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedis()
{
return $this->redis;
}
/**
* Get the underlying Redis instance.
*
* @return \Illuminate\Redis\Database
*/
public function getRedis()
{
return $this->redis;
}
/**
* Get the expiration time in seconds.
*
* @return int|null
*/
public function getExpire()
{
return $this->expire;
}
/**
* Set the expiration time in seconds.
*
* @param int|null $seconds
* @return void
*/
public function setExpire($seconds)
{
$this->expire = $seconds;
}
/**
* Get the expiration time in seconds.
*
* @return int|null
*/
public function getExpire()
{
return $this->expire;
}
/**
* Set the expiration time in seconds.
*
* @param int|null $seconds
* @return void
*/
public function setExpire($seconds)
{
$this->expire = $seconds;
}
}

View File

@@ -1,81 +1,109 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use ReflectionClass;
use ReflectionProperty;
use Illuminate\Contracts\Queue\QueueableEntity;
use Illuminate\Contracts\Database\ModelIdentifier;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
trait SerializesModels {
trait SerializesModels
{
/**
* Prepare the instance for serialization.
*
* @return array
*/
public function __sleep()
{
$properties = (new ReflectionClass($this))->getProperties();
/**
* Prepare the instance for serialization.
*
* @return array
*/
public function __sleep()
{
$properties = (new ReflectionClass($this))->getProperties();
foreach ($properties as $property) {
$property->setValue($this, $this->getSerializedPropertyValue(
$this->getPropertyValue($property)
));
}
foreach ($properties as $property)
{
$property->setValue($this, $this->getSerializedPropertyValue(
$this->getPropertyValue($property)
));
}
return array_map(function ($p) {
return $p->getName();
}, $properties);
}
return array_map(function($p) { return $p->getName(); }, $properties);
}
/**
* Restore the model after serialization.
*
* @return void
*/
public function __wakeup()
{
foreach ((new ReflectionClass($this))->getProperties() as $property) {
$property->setValue($this, $this->getRestoredPropertyValue(
$this->getPropertyValue($property)
));
}
}
/**
* Restore the model after serialization.
*
* @return void
*/
public function __wakeup()
{
foreach ((new ReflectionClass($this))->getProperties() as $property)
{
$property->setValue($this, $this->getRestoredPropertyValue(
$this->getPropertyValue($property)
));
}
}
/**
* Get the property value prepared for serialization.
*
* @param mixed $value
* @return mixed
*/
protected function getSerializedPropertyValue($value)
{
if ($value instanceof QueueableEntity) {
return new ModelIdentifier(get_class($value), $value->getQueueableId());
}
/**
* Get the property value prepared for serialization.
*
* @param mixed $value
* @return mixed
*/
protected function getSerializedPropertyValue($value)
{
return $value instanceof QueueableEntity
? new ModelIdentifier(get_class($value), $value->getQueueableId()) : $value;
}
return $value;
}
/**
* Get the restored property value after deserialization.
*
* @param mixed $value
* @return mixed
*/
protected function getRestoredPropertyValue($value)
{
return $value instanceof ModelIdentifier
? (new $value->class)->findOrFail($value->id) : $value;
}
/**
* Get the restored property value after deserialization.
*
* @param mixed $value
* @return mixed
*/
protected function getRestoredPropertyValue($value)
{
if (! $value instanceof ModelIdentifier) {
return $value;
}
/**
* Get the property value for the given property.
*
* @param \ReflectionProperty $property
* @return mixed
*/
protected function getPropertyValue(ReflectionProperty $property)
{
$property->setAccessible(true);
return is_array($value->id)
? $this->restoreCollection($value)
: (new $value->class)->newQuery()->useWritePdo()->findOrFail($value->id);
}
return $property->getValue($this);
}
/**
* Restore a queueable collection instance.
*
* @param \Illuminate\Contracts\Database\ModelIdentifier $value
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function restoreCollection($value)
{
if (! $value->class || count($value->id) === 0) {
return new EloquentCollection;
}
$model = new $value->class;
return $model->newQuery()->useWritePdo()
->whereIn($model->getKeyName(), $value->id)->get();
}
/**
* Get the property value for the given property.
*
* @param \ReflectionProperty $property
* @return mixed
*/
protected function getPropertyValue(ReflectionProperty $property)
{
$property->setAccessible(true);
return $property->getValue($this);
}
}

View File

@@ -1,127 +1,165 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Aws\Sqs\SqsClient;
use Illuminate\Queue\Jobs\SqsJob;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class SqsQueue extends Queue implements QueueContract {
class SqsQueue extends Queue implements QueueContract
{
/**
* The Amazon SQS instance.
*
* @var \Aws\Sqs\SqsClient
*/
protected $sqs;
/**
* The Amazon SQS instance.
*
* @var \Aws\Sqs\SqsClient
*/
protected $sqs;
/**
* The name of the default tube.
*
* @var string
*/
protected $default;
/**
* The name of the default tube.
*
* @var string
*/
protected $default;
/**
* The sqs prefix url.
*
* @var string
*/
protected $prefix;
/**
* Create a new Amazon SQS queue instance.
*
* @param \Aws\Sqs\SqsClient $sqs
* @param string $default
* @return void
*/
public function __construct(SqsClient $sqs, $default)
{
$this->sqs = $sqs;
$this->default = $default;
}
/**
* The job creator callback.
*
* @var callable|null
*/
protected $jobCreator;
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
/**
* Create a new Amazon SQS queue instance.
*
* @param \Aws\Sqs\SqsClient $sqs
* @param string $default
* @param string $prefix
* @return void
*/
public function __construct(SqsClient $sqs, $default, $prefix = '')
{
$this->sqs = $sqs;
$this->prefix = $prefix;
$this->default = $default;
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
$response = $this->sqs->sendMessage(array('QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload));
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function push($job, $data = '', $queue = null)
{
return $this->pushRaw($this->createPayload($job, $data), $queue);
}
return $response->get('MessageId');
}
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
$response = $this->sqs->sendMessage(['QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload]);
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
return $response->get('MessageId');
}
$delay = $this->getSeconds($delay);
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
$payload = $this->createPayload($job, $data);
return $this->sqs->sendMessage(array(
$delay = $this->getSeconds($delay);
'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, 'DelaySeconds' => $delay,
return $this->sqs->sendMessage([
'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, 'DelaySeconds' => $delay,
))->get('MessageId');
}
])->get('MessageId');
}
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
$queue = $this->getQueue($queue);
$response = $this->sqs->receiveMessage(
array('QueueUrl' => $queue, 'AttributeNames' => array('ApproximateReceiveCount'))
);
$response = $this->sqs->receiveMessage(
['QueueUrl' => $queue, 'AttributeNames' => ['ApproximateReceiveCount']]
);
if (count($response['Messages']) > 0)
{
return new SqsJob($this->container, $this->sqs, $queue, $response['Messages'][0]);
}
}
if (count($response['Messages']) > 0) {
if ($this->jobCreator) {
return call_user_func($this->jobCreator, $this->container, $this->sqs, $queue, $response);
} else {
return new SqsJob($this->container, $this->sqs, $queue, $response['Messages'][0]);
}
}
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
public function getQueue($queue)
{
return $queue ?: $this->default;
}
/**
* Define the job creator callback for the connection.
*
* @param callable $callback
* @return $this
*/
public function createJobsUsing(callable $callback)
{
$this->jobCreator = $callback;
/**
* Get the underlying SQS instance.
*
* @return \Aws\Sqs\SqsClient
*/
public function getSqs()
{
return $this->sqs;
}
return $this;
}
/**
* Get the queue or return the default.
*
* @param string|null $queue
* @return string
*/
public function getQueue($queue)
{
$queue = $queue ?: $this->default;
if (filter_var($queue, FILTER_VALIDATE_URL) !== false) {
return $queue;
}
return rtrim($this->prefix, '/').'/'.($queue);
}
/**
* Get the underlying SQS instance.
*
* @return \Aws\Sqs\SqsClient
*/
public function getSqs()
{
return $this->sqs;
}
}

View File

@@ -1,115 +1,172 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Exception;
use Throwable;
use Illuminate\Queue\Jobs\SyncJob;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Queue\Queue as QueueContract;
class SyncQueue extends Queue implements QueueContract {
class SyncQueue extends Queue implements QueueContract
{
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*
* @throws \Exception|\Throwable
*/
public function push($job, $data = '', $queue = null)
{
$queueJob = $this->resolveJob($this->createPayload($job, $data, $queue));
/**
* Push a new job onto the queue.
*
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
* @throws \Exception
*/
public function push($job, $data = '', $queue = null)
{
$queueJob = $this->resolveJob($this->createPayload($job, $data, $queue));
try {
$this->raiseBeforeJobEvent($queueJob);
try
{
$queueJob->fire();
}
catch(Exception $e)
{
$this->handleFailedJob($queueJob);
$queueJob->fire();
throw $e;
}
$this->raiseAfterJobEvent($queueJob);
} catch (Exception $e) {
$this->raiseExceptionOccurredJobEvent($queueJob, $e);
return 0;
}
$this->handleFailedJob($queueJob);
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = array())
{
//
}
throw $e;
} catch (Throwable $e) {
$this->raiseExceptionOccurredJobEvent($queueJob, $e);
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
return $this->push($job, $data, $queue);
}
$this->handleFailedJob($queueJob);
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
//
}
throw $e;
}
/**
* Resolve a Sync job instance.
*
* @param string $payload
* @return \Illuminate\Queue\Jobs\SyncJob
*/
protected function resolveJob($payload)
{
return new SyncJob($this->container, $payload);
}
return 0;
}
/**
* Handle the failed job
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return array
*/
protected function handleFailedJob(Job $job)
{
$job->failed();
/**
* Push a raw payload onto the queue.
*
* @param string $payload
* @param string $queue
* @param array $options
* @return mixed
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
//
}
$this->raiseFailedJobEvent($job);
}
/**
* Push a new job onto the queue after a delay.
*
* @param \DateTime|int $delay
* @param string $job
* @param mixed $data
* @param string $queue
* @return mixed
*/
public function later($delay, $job, $data = '', $queue = null)
{
return $this->push($job, $data, $queue);
}
/**
* Raise the failed queue job event.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseFailedJobEvent(Job $job)
{
$data = json_decode($job->getRawBody(), true);
/**
* Pop the next job off of the queue.
*
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
public function pop($queue = null)
{
//
}
if($this->container->bound('events'))
{
$this->container['events']->fire('illuminate.queue.failed', array('sync', $job, $data));
}
}
/**
* Resolve a Sync job instance.
*
* @param string $payload
* @return \Illuminate\Queue\Jobs\SyncJob
*/
protected function resolveJob($payload)
{
return new SyncJob($this->container, $payload);
}
/**
* Raise the before queue job event.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseBeforeJobEvent(Job $job)
{
$data = json_decode($job->getRawBody(), true);
if ($this->container->bound('events')) {
$this->container['events']->fire(new Events\JobProcessing('sync', $job, $data));
}
}
/**
* Raise the after queue job event.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseAfterJobEvent(Job $job)
{
$data = json_decode($job->getRawBody(), true);
if ($this->container->bound('events')) {
$this->container['events']->fire(new Events\JobProcessed('sync', $job, $data));
}
}
/**
* Raise the exception occurred queue job event.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param \Throwable $exception
* @return void
*/
protected function raiseExceptionOccurredJobEvent(Job $job, $exception)
{
$data = json_decode($job->getRawBody(), true);
if ($this->container->bound('events')) {
$this->container['events']->fire(new Events\JobExceptionOccurred('sync', $job, $data, $exception));
}
}
/**
* Handle the failed job.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return array
*/
protected function handleFailedJob(Job $job)
{
$job->failed();
$this->raiseFailedJobEvent($job);
}
/**
* Raise the failed queue job event.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseFailedJobEvent(Job $job)
{
$data = json_decode($job->getRawBody(), true);
if ($this->container->bound('events')) {
$this->container['events']->fire(new Events\JobFailed('sync', $job, $data));
}
}
}

View File

@@ -1,364 +1,441 @@
<?php namespace Illuminate\Queue;
<?php
namespace Illuminate\Queue;
use Exception;
use Throwable;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Queue\Failed\FailedJobProviderInterface;
use Illuminate\Contracts\Cache\Repository as CacheContract;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Queue\Failed\FailedJobProviderInterface;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Illuminate\Contracts\Cache\Repository as CacheContract;
class Worker {
class Worker
{
/**
* The queue manager instance.
*
* @var \Illuminate\Queue\QueueManager
*/
protected $manager;
/**
* The queue manager instance.
*
* @var \Illuminate\Queue\QueueManager
*/
protected $manager;
/**
* The failed job provider implementation.
*
* @var \Illuminate\Queue\Failed\FailedJobProviderInterface
*/
protected $failer;
/**
* The failed job provider implementation.
*
* @var \Illuminate\Queue\Failed\FailedJobProviderInterface
*/
protected $failer;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The exception handler instance.
*
* @var \Illuminate\Foundation\Exceptions\Handler
*/
protected $exceptions;
/**
* The exception handler instance.
*
* @var \Illuminate\Foundation\Exceptions\Handler
*/
protected $exceptions;
/**
* Create a new queue worker.
*
* @param \Illuminate\Queue\QueueManager $manager
* @param \Illuminate\Queue\Failed\FailedJobProviderInterface $failer
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function __construct(QueueManager $manager,
/**
* Create a new queue worker.
*
* @param \Illuminate\Queue\QueueManager $manager
* @param \Illuminate\Queue\Failed\FailedJobProviderInterface $failer
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function __construct(QueueManager $manager,
FailedJobProviderInterface $failer = null,
Dispatcher $events = null)
{
$this->failer = $failer;
$this->events = $events;
$this->manager = $manager;
}
{
$this->failer = $failer;
$this->events = $events;
$this->manager = $manager;
}
/**
* Listen to the given queue in a loop.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $memory
* @param int $sleep
* @param int $maxTries
* @return array
*/
public function daemon($connectionName, $queue = null, $delay = 0, $memory = 128, $sleep = 3, $maxTries = 0)
{
$lastRestart = $this->getTimestampOfLastQueueRestart();
/**
* Listen to the given queue in a loop.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $memory
* @param int $sleep
* @param int $maxTries
* @return array
*/
public function daemon($connectionName, $queue = null, $delay = 0, $memory = 128, $sleep = 3, $maxTries = 0)
{
$lastRestart = $this->getTimestampOfLastQueueRestart();
while (true)
{
if ($this->daemonShouldRun())
{
$this->runNextJobForDaemon(
$connectionName, $queue, $delay, $sleep, $maxTries
);
}
else
{
$this->sleep($sleep);
}
while (true) {
if ($this->daemonShouldRun()) {
$this->runNextJobForDaemon(
$connectionName, $queue, $delay, $sleep, $maxTries
);
} else {
$this->sleep($sleep);
}
if ($this->memoryExceeded($memory) || $this->queueShouldRestart($lastRestart))
{
$this->stop();
}
}
}
if ($this->memoryExceeded($memory) || $this->queueShouldRestart($lastRestart)) {
$this->stop();
}
}
}
/**
* Run the next job for the daemon worker.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $sleep
* @param int $maxTries
* @return void
*/
protected function runNextJobForDaemon($connectionName, $queue, $delay, $sleep, $maxTries)
{
try
{
$this->pop($connectionName, $queue, $delay, $sleep, $maxTries);
}
catch (Exception $e)
{
if ($this->exceptions) $this->exceptions->report($e);
}
}
/**
* Run the next job for the daemon worker.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $sleep
* @param int $maxTries
* @return void
*/
protected function runNextJobForDaemon($connectionName, $queue, $delay, $sleep, $maxTries)
{
try {
$this->pop($connectionName, $queue, $delay, $sleep, $maxTries);
} catch (Exception $e) {
if ($this->exceptions) {
$this->exceptions->report($e);
}
} catch (Throwable $e) {
if ($this->exceptions) {
$this->exceptions->report(new FatalThrowableError($e));
}
}
}
/**
* Determine if the daemon should process on this iteration.
*
* @return bool
*/
protected function daemonShouldRun()
{
if ($this->manager->isDownForMaintenance())
{
return false;
}
/**
* Determine if the daemon should process on this iteration.
*
* @return bool
*/
protected function daemonShouldRun()
{
return $this->manager->isDownForMaintenance()
? false : $this->events->until('illuminate.queue.looping') !== false;
}
return $this->events->until('illuminate.queue.looping') !== false;
}
/**
* Listen to the given queue.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $sleep
* @param int $maxTries
* @return array
*/
public function pop($connectionName, $queue = null, $delay = 0, $sleep = 3, $maxTries = 0)
{
try {
$connection = $this->manager->connection($connectionName);
/**
* Listen to the given queue.
*
* @param string $connectionName
* @param string $queue
* @param int $delay
* @param int $sleep
* @param int $maxTries
* @return array
*/
public function pop($connectionName, $queue = null, $delay = 0, $sleep = 3, $maxTries = 0)
{
$connection = $this->manager->connection($connectionName);
$job = $this->getNextJob($connection, $queue);
$job = $this->getNextJob($connection, $queue);
// If we're able to pull a job off of the stack, we will process it and
// then immediately return back out. If there is no job on the queue
// we will "sleep" the worker for the specified number of seconds.
if (! is_null($job)) {
return $this->process(
$this->manager->getName($connectionName), $job, $maxTries, $delay
);
}
} catch (Exception $e) {
if ($this->exceptions) {
$this->exceptions->report($e);
}
}
// If we're able to pull a job off of the stack, we will process it and
// then immediately return back out. If there is no job on the queue
// we will "sleep" the worker for the specified number of seconds.
if ( ! is_null($job))
{
return $this->process(
$this->manager->getName($connectionName), $job, $maxTries, $delay
);
}
$this->sleep($sleep);
$this->sleep($sleep);
return ['job' => null, 'failed' => false];
}
return ['job' => null, 'failed' => false];
}
/**
* Get the next job from the queue connection.
*
* @param \Illuminate\Contracts\Queue\Queue $connection
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
protected function getNextJob($connection, $queue)
{
if (is_null($queue)) {
return $connection->pop();
}
/**
* Get the next job from the queue connection.
*
* @param \Illuminate\Queue\Queue $connection
* @param string $queue
* @return \Illuminate\Contracts\Queue\Job|null
*/
protected function getNextJob($connection, $queue)
{
if (is_null($queue)) return $connection->pop();
foreach (explode(',', $queue) as $queue) {
if (! is_null($job = $connection->pop($queue))) {
return $job;
}
}
}
foreach (explode(',', $queue) as $queue)
{
if ( ! is_null($job = $connection->pop($queue))) return $job;
}
}
/**
* Process a given job from the queue.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @param int $maxTries
* @param int $delay
* @return array|null
*
* @throws \Throwable
*/
public function process($connection, Job $job, $maxTries = 0, $delay = 0)
{
if ($maxTries > 0 && $job->attempts() > $maxTries) {
return $this->logFailedJob($connection, $job);
}
/**
* Process a given job from the queue.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @param int $maxTries
* @param int $delay
* @return void
*
* @throws \Exception
*/
public function process($connection, Job $job, $maxTries = 0, $delay = 0)
{
if ($maxTries > 0 && $job->attempts() > $maxTries)
{
return $this->logFailedJob($connection, $job);
}
try {
$this->raiseBeforeJobEvent($connection, $job);
try
{
// First we will fire off the job. Once it is done we will see if it will
// be auto-deleted after processing and if so we will go ahead and run
// the delete method on the job. Otherwise we will just keep moving.
$job->fire();
// First we will fire off the job. Once it is done we will see if it will be
// automatically deleted after processing and if so we'll fire the delete
// method on the job. Otherwise, we will just keep on running our jobs.
$job->fire();
return ['job' => $job, 'failed' => false];
}
$this->raiseAfterJobEvent($connection, $job);
catch (Exception $e)
{
// If we catch an exception, we will attempt to release the job back onto
// the queue so it is not lost. This will let is be retried at a later
// time by another listener (or the same one). We will do that here.
if ( ! $job->isDeleted()) $job->release($delay);
return ['job' => $job, 'failed' => false];
} catch (Exception $e) {
$this->handleJobException($connection, $job, $delay, $e);
} catch (Throwable $e) {
$this->handleJobException($connection, $job, $delay, $e);
}
}
throw $e;
}
}
/**
* Handle an exception that occurred while the job was running.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @param int $delay
* @param \Throwable $e
* @return void
*
* @throws \Throwable
*/
protected function handleJobException($connection, Job $job, $delay, $e)
{
// If we catch an exception, we will attempt to release the job back onto
// the queue so it is not lost. This will let is be retried at a later
// time by another listener (or the same one). We will do that here.
try {
$this->raiseExceptionOccurredJobEvent(
$connection, $job, $e
);
} finally {
if (! $job->isDeleted()) {
$job->release($delay);
}
}
/**
* Log a failed job into storage.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @return array
*/
protected function logFailedJob($connection, Job $job)
{
if ($this->failer)
{
$this->failer->log($connection, $job->getQueue(), $job->getRawBody());
throw $e;
}
$job->delete();
/**
* Raise the before queue job event.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseBeforeJobEvent($connection, Job $job)
{
if ($this->events) {
$data = json_decode($job->getRawBody(), true);
$job->failed();
$this->events->fire(new Events\JobProcessing($connection, $job, $data));
}
}
$this->raiseFailedJobEvent($connection, $job);
}
/**
* Raise the after queue job event.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseAfterJobEvent($connection, Job $job)
{
if ($this->events) {
$data = json_decode($job->getRawBody(), true);
return ['job' => $job, 'failed' => true];
}
$this->events->fire(new Events\JobProcessed($connection, $job, $data));
}
}
/**
* Raise the failed queue job event.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
protected function raiseFailedJobEvent($connection, Job $job)
{
if ($this->events)
{
$data = json_decode($job->getRawBody(), true);
/**
* Raise the exception occurred queue job event.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @param \Throwable $exception
* @return void
*/
protected function raiseExceptionOccurredJobEvent($connection, Job $job, $exception)
{
if ($this->events) {
$data = json_decode($job->getRawBody(), true);
$this->events->fire('illuminate.queue.failed', array($connection, $job, $data));
}
}
$this->events->fire(new Events\JobExceptionOccurred($connection, $job, $data, $exception));
}
}
/**
* Determine if the memory limit has been exceeded.
*
* @param int $memoryLimit
* @return bool
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
}
/**
* Log a failed job into storage.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @return array
*/
protected function logFailedJob($connection, Job $job)
{
if ($this->failer) {
$failedId = $this->failer->log($connection, $job->getQueue(), $job->getRawBody());
/**
* Stop listening and bail out of the script.
*
* @return void
*/
public function stop()
{
$this->events->fire('illuminate.queue.stopping');
$job->delete();
die;
}
$job->failed();
/**
* Sleep the script for a given number of seconds.
*
* @param int $seconds
* @return void
*/
public function sleep($seconds)
{
sleep($seconds);
}
$this->raiseFailedJobEvent($connection, $job, $failedId);
}
/**
* Get the last queue restart timestamp, or null.
*
* @return int|null
*/
protected function getTimestampOfLastQueueRestart()
{
if ($this->cache)
{
return $this->cache->get('illuminate:queue:restart');
}
}
return ['job' => $job, 'failed' => true];
}
/**
* Determine if the queue worker should restart.
*
* @param int|null $lastRestart
* @return bool
*/
protected function queueShouldRestart($lastRestart)
{
return $this->getTimestampOfLastQueueRestart() != $lastRestart;
}
/**
* Raise the failed queue job event.
*
* @param string $connection
* @param \Illuminate\Contracts\Queue\Job $job
* @param int|null $failedId
* @return void
*/
protected function raiseFailedJobEvent($connection, Job $job, $failedId)
{
if ($this->events) {
$data = json_decode($job->getRawBody(), true);
/**
* Set the exception handler to use in Daemon mode.
*
* @param \Illuminate\Contracts\Debug\ExceptionHandler $handler
* @return void
*/
public function setDaemonExceptionHandler(ExceptionHandler $handler)
{
$this->exceptions = $handler;
}
$this->events->fire(new Events\JobFailed($connection, $job, $data, $failedId));
}
}
/**
* Set the cache repository implementation.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function setCache(CacheContract $cache)
{
$this->cache = $cache;
}
/**
* Determine if the memory limit has been exceeded.
*
* @param int $memoryLimit
* @return bool
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
}
/**
* Get the queue manager instance.
*
* @return \Illuminate\Queue\QueueManager
*/
public function getManager()
{
return $this->manager;
}
/**
* Stop listening and bail out of the script.
*
* @return void
*/
public function stop()
{
$this->events->fire(new Events\WorkerStopping);
/**
* Set the queue manager instance.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
public function setManager(QueueManager $manager)
{
$this->manager = $manager;
}
die;
}
/**
* Sleep the script for a given number of seconds.
*
* @param int $seconds
* @return void
*/
public function sleep($seconds)
{
sleep($seconds);
}
/**
* Get the last queue restart timestamp, or null.
*
* @return int|null
*/
protected function getTimestampOfLastQueueRestart()
{
if ($this->cache) {
return $this->cache->get('illuminate:queue:restart');
}
}
/**
* Determine if the queue worker should restart.
*
* @param int|null $lastRestart
* @return bool
*/
protected function queueShouldRestart($lastRestart)
{
return $this->getTimestampOfLastQueueRestart() != $lastRestart;
}
/**
* Set the exception handler to use in Daemon mode.
*
* @param \Illuminate\Contracts\Debug\ExceptionHandler $handler
* @return void
*/
public function setDaemonExceptionHandler(ExceptionHandler $handler)
{
$this->exceptions = $handler;
}
/**
* Set the cache repository implementation.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function setCache(CacheContract $cache)
{
$this->cache = $cache;
}
/**
* Get the queue manager instance.
*
* @return \Illuminate\Queue\QueueManager
*/
public function getManager()
{
return $this->manager;
}
/**
* Set the queue manager instance.
*
* @param \Illuminate\Queue\QueueManager $manager
* @return void
*/
public function setManager(QueueManager $manager)
{
$this->manager = $manager;
}
}

View File

@@ -14,14 +14,14 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/console": "5.0.*",
"illuminate/contracts": "5.0.*",
"illuminate/container": "5.0.*",
"illuminate/http": "5.0.*",
"illuminate/support": "5.0.*",
"symfony/process": "2.6.*",
"nesbot/carbon": "~1.0"
"php": ">=5.5.9",
"illuminate/console": "5.2.*",
"illuminate/container": "5.2.*",
"illuminate/contracts": "5.2.*",
"illuminate/support": "5.2.*",
"nesbot/carbon": "~1.20",
"symfony/debug": "2.8.*|3.0.*",
"symfony/process": "2.8.*|3.0.*"
},
"autoload": {
"psr-4": {
@@ -33,14 +33,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.2-dev"
}
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver (~2.4).",
"illuminate/redis": "Required to use the redis queue driver (5.0.*).",
"iron-io/iron_mq": "Required to use the iron queue driver (~1.5).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0)."
"aws/aws-sdk-php": "Required to use the SQS queue driver (~3.0).",
"illuminate/redis": "Required to use the Redis queue driver (5.2.*).",
"pda/pheanstalk": "Required to use the Beanstalk queue driver (~3.0)."
},
"minimum-stability": "dev"
}