2

How can I access Yii models outside of the framework?

I have some gearman workers performing tasks and are managed using BrianMoons GearmanManager. I'd like to be able to access a few Yii models in the worker's script without have to load the whole Yii framework. What do I need to import to load the models in my script? (CActiverecord, DBconnection, etc).

A worker looks like this:

as simple function

function reverse_string($job, &$log) {

    $workload = $job->workload();

    $result = strrev($workload);

    $log[] = "Success";

    return $result;

}

?>

or as a class:

<?php

class Sum {

    private $cache = array();

    private $foo = 0;

    public function run($job, &$log) {

        $workload = $job->workload();

        if(empty($this->cache[$workload])){

            $dat = json_decode($workload, true);

            $sum = 0;

            foreach($dat as $d){
                $sum+=$d;
                sleep(1);
            }

            $this->cache[$workload] = $sum + 0;

        } else {

            $sum = $this->cache[$workload] + 0;

        }

    $log[] = "Answer: ".$sum;

    $this->foo = 1;

    return $sum;

}

}

?>

I'd like to be able to access a few models and perform operations within the worker like so:

$foo=Foo::model()->findByPk($id);
$foo->attribute="bar";
$foo->save();
dandan
  • 1,016
  • 8
  • 16

1 Answers1

0

To be able to use Yii's models you need to create a Yii console command and execute it. In your case it's pretty simple:

First of all, you need to extend GearmanWorker class (available in PHP Gearman extension) and implement your worker class:

class SumWorker extends GearmanWorker {
    // your real code here
    public function doSomethingUseful( $job ) {
        $workload = $job->workload();
        echo "Job: " . $job->handle() . PHP_EOL;
        $args = json_decode( $workload );

        // actual code
    }
}

then create a Yii console command:

class SumCommand extends CConsoleCommand {
    public function run($args) {
        $worker = new SumWorker();

        $worker->addServer();
        $worker->addFunction("doSomethingUseful", array($worker, "doSomethingUseful"));

        while (1) {
            print "Waiting for job...\n";

            $ret = $worker->work();

            if ( $worker->returnCode() != GEARMAN_SUCCESS ) break;
        }
     }
 }
Valentin Rodygin
  • 864
  • 5
  • 12
  • Thanks Valentin. What I don't understand is running the worker part with GearmanManager. It has a folder where you drop the worker code in and it manages everything (worker examples above). How can those workers access Yii? It won't be running through yiic. I know your example will work if I open up a terminal window and run ./yiic Sumcommand, but using GearmanManager sounds better for production. Do you usually just run these ./yiic commands from supervisor? To my understanding that'd be the only way to get your suggestion to work on a production server. – dandan Oct 31 '14 at 17:36