2014-01-26 40 views
3
class Job extends \Stackable 
{ 
    public function __construct($monitor) 
    { 
     $this->monitor = $monitor; 
    } 
    public function run() 
    { 
     curl_setopt($this->ch, CURLOPT_URL, $this->monitor->getIp()); 
     $request = json_decode(curl_exec($this->ch), true); 
     //some more db transactions 
     $this->em->persist 
     (
      (new Attempt()) 
       ->setMonitor($this->monitor) 
       ->setTimestamp(new \DateTime()) 
       ->setLatency($request['latency']) 
     ); 
     $this->em->flush(); 
    } 
} 

class ProbeWorker extends \Worker 
{ 
    public function __construct($em) 
    { 
     $this->em = $em; 
     $this->ch = curl_init(); 
    } 
    public function run() 
    { 
     curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 
    } 
} 

class DogeCommand extends ContainerAwareCommand 
{ 
    protected function configure() 
    { 
     $this 
      ->setName('wow:doge') 
      ->setDescription('such speed') 
     ; 
    } 
    protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     $em = $this->getContainer()->get('doctrine')->getManager(); 
     $monitors = $em->getRepository('WowABundle:Monitor')->findAll(); 
     $worker = new ProbeWorker($em); 
     $worker->start(); 
     foreach($monitors as $monitor) 
     { 
      $job = new ProbeJob($monitor); 
      $worker->stack($job); 
     } 
    } 
} 

这给了我一个主义实体管理多线程坚持和冲洗

[PDOException]          
    You cannot serialize or unserialize PDO instances 

错误。那有什么意思?我简要介绍了旧实现的性能,它可以连续处理它,并且我花了一半时间来冲洗。将它分成更小的块没有帮助。循环的每次迭代需要1秒钟的时间,所以通过并行化,假设硬件有能力,我可以显着缩短运行时间并扩展到更多网站。有没有办法做到这一点?我该如何解决?

我确定每个作业都是真正独立于彼此的,并且不会有任何冲突的db事务。一切都是插入或读取。

回答

0

工作人员应该在run方法中初始化curl,而不是构造函数。

$ ch资源在执行期间可以通过$ this-> worker-> ch进行堆栈。

您遇到的错误是因为您将$ em写入对象作用域,它不会从pthreads下降,因此不是线程安全的,因此pthreads会尝试序列化对象以进行安全存储,但对象是不可序列化,所以你会遇到你所显示的错误。

解决方法是避免设置该成员,为每个Worker初始化对象的实例,我可能会存储在静态作用域中以避免序列化和访问这些复杂对象时互斥体的不必要开销。

+0

哇!作者自己的回答。既然我不能在'Stackable'上共享'$ em',我应该使用'Thread'类吗? –