2
votes

I have to parse a huge csv files in a Yii 1.1 Application. Each row has to be validated and saved to the database. I decided to use Multi Threading for this task.

So here is my code in the Controller action:

public function parseData($) {
        $this->content = explode("\n", $this->content);

        $thread_1 = new DatalogThread(array_slice($this->content, 0, 7000));
        $thread_2 = new DatalogThread(array_slice($this->content, 7001));

        $thread_1->start();
        $thread_2->start();
    }

And the Thread (I put it in models folder):

class DatalogThread extends Thread {
    public $content;


    public function __construct($content) {
       $this->content = $content;

    }


    public function run() {
       foreach ($this->content as $value) {
            $row = str_getcsv($value);

            $datalog = new Datalog($row);
            $datalog->save();

        }
    }

}

The problem is that the Thread does not get access to the model file:

Fatal error: Class 'Datalog' not found in C:\xampp...\protected\models\DatalogThread.php

I tried Yii::autoload("Datalog"), but got The following error:

Fatal error: Cannot access property Yii::$_coreClasses in ...\YiiMain\framework\YiiBase.php on line 402

1
where is the "Datalog" class defined ? - Rishav Rastogi
make sure you check the filename format and classname are correct. - Rishav Rastogi
Autoloading of classes is done bei Yii Framework. Im sure everything is set up correctly, because if I use $thread_1->run() instead of $thread_1->start() in the controller action everything works fine, but without Thread functionality. - xerxes

1 Answers

0
votes

Yii uses a LOT of statics, this is not the best kind of code for multi-threading.

What you want to do is initialize threads that are not aware of Yii and reload it, I do not use Yii, but here's some working out to give you an idea of what to do:

<?php
define ("MY_YII_PATH", "/usr/src/yii/framework/yii.php");

include (MY_YII_PATH);

class YiiThread extends Thread {
    public $path;
    public $config;

    public function __construct($path, $config = array()) {
        $this->path = $path;
        $this->config = $config;
    }

    public function run() {
        include (
            $this->path);
        /* create sub application here */

    }
}

$t = new YiiThread(MY_YII_PATH);
$t->start(PTHREADS_INHERIT_NONE);
?>

This will work much better ... I should think you want what yii calls a console application in your threads, because you don't want it trying to send any headers or anything like that ...

That should get you started ...