├── GearmanComponent.php ├── GearmanController.php ├── JobBase.php ├── JobInterface.php ├── JobWorkload.php ├── README.md └── composer.json /GearmanComponent.php: -------------------------------------------------------------------------------- 1 | _application === null) { 30 | $app = new Application($this->getConfig(), $this->getProcess()); 31 | foreach($this->jobs as $name => $job) { 32 | $job = Yii::createObject($job); 33 | if(!($job instanceof JobInterface)) { 34 | throw new \yii\base\InvalidConfigException('Gearman job must be instance of JobInterface.'); 35 | } 36 | 37 | $job->setName($name); 38 | $app->add($job); 39 | } 40 | $this->_application = $app; 41 | } 42 | 43 | return $this->_application; 44 | } 45 | 46 | public function getDispatcher() 47 | { 48 | if($this->_dispatcher === null) { 49 | $this->_dispatcher = new Dispatcher($this->getConfig()); 50 | } 51 | 52 | return $this->_dispatcher; 53 | } 54 | 55 | public function getConfig() 56 | { 57 | if($this->_config === null) { 58 | $servers = []; 59 | foreach($this->servers as $server) { 60 | if(is_array($server) && isset($server['host'], $server['port'])) { 61 | $servers[] = implode(Config::SERVER_PORT_SEPARATOR, [$server['host'], $server['port']]); 62 | } else { 63 | $servers[] = $server; 64 | } 65 | } 66 | 67 | $this->_config = new Config([ 68 | 'servers' => $servers, 69 | 'user' => $this->user 70 | ]); 71 | } 72 | 73 | return $this->_config; 74 | } 75 | 76 | public function setConfig(Config $config) 77 | { 78 | $this->_config = $config; 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return Process 84 | */ 85 | public function getProcess() 86 | { 87 | if ($this->_process === null) { 88 | $this->setProcess((new Process($this->getConfig()))); 89 | } 90 | return $this->_process; 91 | } 92 | 93 | /** 94 | * @param Process $process 95 | * @return $this 96 | */ 97 | public function setProcess(Process $process) 98 | { 99 | if ($this->getConfig() === null && $process->getConfig() instanceof Config) { 100 | $this->setConfig($process->getConfig()); 101 | } 102 | $this->_process = $process; 103 | return $this; 104 | } 105 | } -------------------------------------------------------------------------------- /GearmanController.php: -------------------------------------------------------------------------------- 1 | getApplication(); 23 | $process = $app->getProcess(); 24 | 25 | if ($process->isRunning()) { 26 | $this->stdout("Failed: Process is already running\n", Console::FG_RED); 27 | return; 28 | } 29 | 30 | $this->runApplication($app); 31 | } 32 | 33 | public function actionStop() 34 | { 35 | $app = $this->getApplication(); 36 | $process = $app->getProcess(); 37 | 38 | if ($process->isRunning()) { 39 | $this->stdout("Success: Process is stopped\n", Console::FG_GREEN); 40 | } else { 41 | $this->stdout("Failed: Process is not stopped\n", Console::FG_RED); 42 | } 43 | 44 | $process->stop(); 45 | } 46 | 47 | public function actionRestart() 48 | { 49 | $app = $this->getApplication(); 50 | $process = $app->getProcess(); 51 | 52 | if (!$process->isRunning()) { 53 | $this->stdout("Failed: Process is not running\n", Console::FG_RED); 54 | return; 55 | } 56 | 57 | unlink($process->getPidFile()); 58 | $process->release(); 59 | 60 | $int = 0; 61 | while ($int < 1000) { 62 | if (file_exists($process->getPidFile())) { 63 | usleep(1000); 64 | $int++; 65 | } elseif (file_exists($process->getLockFile())) { 66 | $process->release(); 67 | usleep(1000); 68 | $int++; 69 | } else { 70 | $int = 1000; 71 | } 72 | } 73 | 74 | $app->setProcess(new Process($app->getConfig(), $app->getLogger())); 75 | $this->runApplication($app); 76 | } 77 | 78 | public function options($id) 79 | { 80 | $options = []; 81 | if(in_array($id, ['start', 'restart'])) { 82 | $options = ['fork']; 83 | } 84 | 85 | return array_merge(parent::options($id), $options); 86 | } 87 | 88 | protected function getApplication() 89 | { 90 | $component = Yii::$app->get($this->gearmanComponent); 91 | return $component->getApplication(); 92 | } 93 | 94 | protected function runApplication(Application $app) 95 | { 96 | $fork = (bool) $this->fork; 97 | if($fork) { 98 | $this->stdout("Success: Process is started\n", Console::FG_GREEN); 99 | } else { 100 | $this->stdout("Success: Process is started, but not daemonized\n", Console::FG_YELLOW); 101 | } 102 | 103 | $app->run((bool) $this->fork); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /JobBase.php: -------------------------------------------------------------------------------- 1 | name; 15 | } 16 | 17 | /** 18 | * @var $name string 19 | */ 20 | public function setName($name) 21 | { 22 | $this->name = $name; 23 | } 24 | 25 | /** 26 | * @param \GearmanJob $job 27 | * @return \filsh\yii2\gearman\JobWorkload 28 | */ 29 | protected function getWorkload(\GearmanJob $job) 30 | { 31 | $workload = null; 32 | if($data = $job->workload()) { 33 | $workload = unserialize($data); 34 | } 35 | return $workload; 36 | } 37 | } -------------------------------------------------------------------------------- /JobInterface.php: -------------------------------------------------------------------------------- 1 | params = $params; 12 | } 13 | 14 | public function getParams() 15 | { 16 | return $this->params; 17 | } 18 | 19 | public function serialize() 20 | { 21 | return serialize($this->params); 22 | } 23 | 24 | public function unserialize($serialized) 25 | { 26 | $this->params = unserialize($serialized); 27 | } 28 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yii2-gearman 2 | ============ 3 | 4 | A wrapper for https://github.com/sinergi/gearman 5 | Thanks for Gabriel Bull 6 | 7 | ## Installation 8 | 9 | It is recommended that you install the Gearman library [through composer](http://getcomposer.org/). To do so, add the following lines to your ``composer.json`` file. 10 | 11 | ```json 12 | { 13 | "require": { 14 | "filsh/yii2-gearman": "dev-master" 15 | } 16 | } 17 | ``` 18 | 19 | ## Configuration 20 | 21 | ```php 22 | 'components' => [ 23 | 'gearman' => [ 24 | 'class' => 'filsh\yii2\gearman\GearmanComponent', 25 | 'servers' => [ 26 | ['host' => '127.0.0.1', 'port' => 4730], 27 | ], 28 | 'user' => 'www-data', 29 | 'jobs' => [ 30 | 'syncCalendar' => [ 31 | 'class' => 'common\jobs\SyncCalendar' 32 | ], 33 | ... 34 | ] 35 | ] 36 | ], 37 | ... 38 | 'controllerMap' => [ 39 | 'gearman' => [ 40 | 'class' => 'filsh\yii2\gearman\GearmanController', 41 | 'gearmanComponent' => 'gearman' 42 | ], 43 | ... 44 | ], 45 | ``` 46 | 47 | ## Job example 48 | 49 | ```php 50 | namespace common\jobs; 51 | 52 | use filsh\yii2\gearman\JobBase; 53 | 54 | class SyncCalendar extends JobBase 55 | { 56 | public function execute(\GearmanJob $job = null) 57 | { 58 | // Do something 59 | } 60 | } 61 | ``` 62 | 63 | ## Manage workers 64 | 65 | ```cmd 66 | yii gearman/start --fork=true // start the workers as a daemon and fork proces 67 | yii gearman/restart --fork=true // restart workers 68 | yii gearman/stop // stop workers 69 | ``` 70 | 71 | ## Example using Dispatcher 72 | 73 | ```php 74 | Yii::$app->gearman->getDispatcher()->background('syncCalendar', new JobWorkload([ 75 | 'params' => [ 76 | 'data' => 'value' 77 | ] 78 | ])); // run in background 79 | Yii::$app->gearman->getDispatcher()->execute('syncCalendar', ['data' => 'value']); // run synchronize 80 | ``` 81 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filsh/yii2-gearman", 3 | "description": "Gearman handler for PHP", 4 | "keywords": ["yii", "extension"], 5 | "homepage": "https://github.com/filsh/yii2-gearman", 6 | "type": "yii2-extension", 7 | "license": "MIT", 8 | "support": { 9 | "email": "imaliy.filsh@gmail.com", 10 | "source": "https://github.com/filsh/yii2-gearman" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Igor Maliy", 15 | "email": "imaliy.filsh@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "yiisoft/yii2": "*", 20 | "sinergi/gearman": "dev-master" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "filsh\\yii2\\gearman\\": "" 25 | } 26 | } 27 | } 28 | --------------------------------------------------------------------------------