├── .gitignore ├── .travis.yml ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Pafelin │ └── Gearman │ │ ├── Connectors │ │ └── GearmanConnector.php │ │ ├── GearmanQueue.php │ │ ├── GearmanServiceProvider.php │ │ └── Jobs │ │ └── GearmanJob.php └── config │ └── config.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | 8 | before_script: 9 | - curl -s http://getcomposer.org/installer | php 10 | - php composer.phar install --dev 11 | 12 | script: phpunit -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | This package gives you the possibily to add gearman as native queue back-end service 4 | 5 | #Installation 6 | 7 | first you need to add it to your composer.json 8 | 9 | second, in `config/app.php`, you need to comment out the native queue service provider 10 | 11 | //'Illuminate\Queue\QueueServiceProvider', 12 | 13 | and to put this instead: 14 | 15 | 'Pafelin\Gearman\GearmanServiceProvider', 16 | 17 | Then in your config/queue.php file you can add: 18 | 19 | 'default' => 'gearman', 20 | 'connections' => array( 21 | 'gearman' => array( 22 | 'driver' => 'gearman', 23 | 'host' => 'localserver.6min.local', 24 | 'queue' => 'default', 25 | 'port' => 4730, 26 | 'timeout' => 1000 //milliseconds 27 | ) 28 | ) 29 | 30 | or, if you have multiple gearman servers: 31 | 32 | 'default' => 'gearman', 33 | 'connections' => array( 34 | 'gearman' => array( 35 | 'driver' => 'gearman', 36 | 'hosts' => array( 37 | array('host' => 'localserver.6min.local', 'port' => 4730), 38 | array('host' => 'localserver2.6min.local', 'port' => 4730), 39 | ), 40 | 'queue' => 'default', 41 | 'timeout' => 1000 //milliseconds 42 | ) 43 | ) 44 | 45 | Then in your code you can add code as (this is the native way to add jobs to the queue): 46 | 47 | Queue::push('SomeClass', array('message' => 'The data that should be available in the SomeClass@fire method')); 48 | 49 | Small hint, you can call Namespaced classes and everything that is written in the docs of laravel for calling custom methods is valid here, too. 50 | 51 | 52 | # Example: 53 | 54 | I add a "service" folder to my app folder and inside I create a file "SendMail.php" 55 | The code of the class is here: 56 | 57 | 'Message №' . $row)); 78 | } 79 | }); 80 | 81 | Finally I just run on my console: 82 | 83 | php artisan queue:listen 84 | 85 | And I go to check what's on my email 86 | 87 | #Bugs 88 | 89 | Please if you notice a bug open an issue or submit request. 90 | 91 | Hope this package will help you 92 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pafelin/gearman", 3 | "description": "Gearman provider for queues in laravel4", 4 | "license" : "MIT", 5 | "authors": [ 6 | { 7 | "name": "Pavel Genov", 8 | "email": "pavel@taskprocess.com" 9 | } 10 | ], 11 | "require": { 12 | "php": ">=5.3.0", 13 | "illuminate/support": "5.*|^6.0|^7.0" 14 | }, 15 | "autoload": { 16 | "psr-0": { 17 | "Pafelin\\Gearman": "src/" 18 | } 19 | }, 20 | "minimum-stability": "dev" 21 | } 22 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Pafelin/Gearman/Connectors/GearmanConnector.php: -------------------------------------------------------------------------------- 1 | addServer($server['host'], $server['port']); 23 | $worker->addServer($server['host'], $server['port']); 24 | } 25 | } else { 26 | $client->addServer($config['host'], $config['port']); 27 | $worker->addServer($config['host'], $config['port']); 28 | } 29 | 30 | $this->setTimeout($client, $config); 31 | 32 | return new GearmanQueue ($client, $worker, $config['queue']); 33 | } 34 | 35 | /** 36 | * @param GearmanClient $client 37 | * @param array $config 38 | */ 39 | private function setTimeout(GearmanClient $client, array $config) 40 | { 41 | if(isset ($config['timeout']) && is_numeric($config['timeout'])) { 42 | $client->setTimeout($config['timeout']); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Pafelin/Gearman/GearmanQueue.php: -------------------------------------------------------------------------------- 1 | client = $client; 43 | $this->worker = $worker; 44 | $this->queue = $queue; 45 | } 46 | 47 | /** 48 | * Push job to the queue 49 | * 50 | * @param string $job 51 | * @param string $data 52 | * @param string|null $queue 53 | * @return int|mixed Return gearman code 54 | */ 55 | public function push($job, $data = '', $queue = null) 56 | { 57 | if(!$queue) { 58 | $queue = $this->queue; 59 | } 60 | $payload = $this->createPayload($job, $data); 61 | 62 | $this->doBackgroundAndHandleException($queue, $payload); 63 | 64 | return $this->client->returnCode(); 65 | } 66 | 67 | /** 68 | * Do the actual handling from the gearmand worker. On error it throws an exception 69 | * 70 | * @param $queue 71 | * @param $payload 72 | * 73 | * @throws GearmanException 74 | */ 75 | private function doBackgroundAndHandleException($queue, $payload) 76 | { 77 | try { 78 | $this->client->doBackground($queue, $payload); 79 | } catch (Exception $e) { 80 | throw new GearmanException($e); 81 | } 82 | } 83 | 84 | /** 85 | * It is not supported from the gearmand driver 86 | * 87 | * @param $delay 88 | * @param $job 89 | * @param string $data 90 | * @param null $queue 91 | * 92 | * @throws Exception 93 | */ 94 | public function later($delay, $job, $data = '', $queue = null) 95 | { 96 | throw new Exception('Gearman driver do not support the method later'); 97 | } 98 | 99 | /** 100 | * take a job from the queue 101 | * 102 | * @param null $queue 103 | * @return \Illuminate\Queue\Jobs\Job|\Illuminate\Queue\null|GearmanJob 104 | */ 105 | public function pop($queue = null) 106 | { 107 | if(!$queue) { 108 | $queue = $this->queue; 109 | } 110 | 111 | return new GearmanJob($this->container, $this->worker, $queue); 112 | } 113 | 114 | /** 115 | * It is not supported from the gearmand driver 116 | * 117 | * @param string $payload 118 | * @param string $queue 119 | * @param array $options 120 | * @throws \Exception 121 | * @return mixed 122 | */ 123 | public function pushRaw($payload, $queue = null, array $options = array()) 124 | { 125 | throw new Exception('Gearman driver do not support the method pushRaw'); 126 | } 127 | 128 | /** 129 | * Get the size of the queue. 130 | * 131 | * @param string $queue 132 | * @return int 133 | */ 134 | public function size($queue = null) 135 | { 136 | return 0; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Pafelin/Gearman/GearmanServiceProvider.php: -------------------------------------------------------------------------------- 1 | registerGearmanConnector($manager); 19 | } 20 | 21 | /** 22 | * Register the Gearman queue connector. 23 | * 24 | * @param \Illuminate\Queue\QueueManager $manager 25 | * @return void 26 | */ 27 | public function registerGearmanConnector($manager) 28 | { 29 | $manager->addConnector('gearman', function() { 30 | return new GearmanConnector(); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Pafelin/Gearman/Jobs/GearmanJob.php: -------------------------------------------------------------------------------- 1 | container = $container; 25 | $this->worker = $worker; 26 | $this->worker->addFunction($queue, array($this, 'onGearmanJob')); 27 | } 28 | 29 | public function fire(){ 30 | 31 | $startTime = time(); 32 | 33 | while($this->worker->work() || $this->worker->returnCode() == GEARMAN_TIMEOUT) { 34 | // Check for expiry. 35 | if((time() - $startTime) >= 60 * $this->maxRunTime) { 36 | echo sprintf('%s minutes have elapsed, expiring.', $this->maxRunTime) . PHP_EOL; 37 | break; 38 | } 39 | } 40 | } 41 | 42 | public function delete(){ 43 | parent::delete(); 44 | } 45 | 46 | public function release($delay = 0) { 47 | if ($delay > 0) { 48 | throw new Exception('No delay is suported'); 49 | } 50 | } 51 | 52 | public function attempts() { 53 | return 1; 54 | } 55 | 56 | public function getJobId() { 57 | return base64_encode($this->job); 58 | } 59 | 60 | public function getContainer() { 61 | return $this->container; 62 | } 63 | 64 | public function getGearmanWorker() { 65 | return $this->worker; 66 | } 67 | 68 | public function onGearmanJob(\GearmanJob $job) { 69 | $this->rawPayload = $job->workload(); 70 | 71 | $payload = json_decode($this->rawPayload, true); 72 | 73 | if (method_exists($this, 'resolveAndFire')) { 74 | $this->resolveAndFire($payload); 75 | return; 76 | } 77 | 78 | // compatibility with Laravel 5.4+ 79 | if (class_exists(JobName::class)) { 80 | list($class, $method) = JobName::parse($payload['job']); 81 | } else { 82 | list($class, $method) = $this->parseJob($payload['job']); 83 | } 84 | 85 | $this->instance = $this->resolve($class); 86 | $this->instance->{$method}($this, $payload['data']); 87 | } 88 | 89 | /** 90 | * Get the raw body string for the job. 91 | * 92 | * @return string 93 | */ 94 | public function getRawBody() { 95 | return $this->rawPayload; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | 'gearman', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Queue Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may configure the connection information for each server that 26 | | is used by your application. A default configuration has been added 27 | | for each back-end shipped with Laravel. You are free to add more. 28 | | 29 | */ 30 | 31 | 'connections' => array( 32 | 'gearman' => array( 33 | 'driver' => 'gearman', 34 | 'host' => 'localhost', 35 | 'queue' => 'default', 36 | 'port' => '4730', 37 | 'timeout' => 1000, //milliseconds 38 | ), 39 | 40 | ), 41 | 42 | ); 43 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafelin/laravel-gearman/437ab1d5a053056f7f516a6e76b7e99cb8d265bb/tests/.gitkeep --------------------------------------------------------------------------------