/** * Run main process */ protected function runMain() { $startTS = microtime_float(); $searchEngine = new eZSolr(); $processLimit = min($this->Options['conc'] ? $this->Options['conc'] : 2, 10); // Maximum 10 processes $useFork = function_exists('pcntl_fork') && function_exists('posix_kill'); if ($useFork) { $this->CLI->output('Using fork.'); } else { $processLimit = 1; } $this->CLI->output('Using ' . $processLimit . ' concurent process(es)'); $processList = array(); for ($i = 0; $i < $processLimit; $i++) { $processList[$i] = -1; } $this->ObjectCount = $this->objectCount(); $this->CLI->output('Number of objects to index: ' . $this->ObjectCount); $this->Script->resetIteration($this->ObjectCount, 0); $topNodeArray = eZPersistentObject::fetchObjectList(eZContentObjectTreeNode::definition(), null, array('parent_node_id' => 1, 'depth' => 1)); // Loop through top nodes. foreach ($topNodeArray as $node) { $nodeID = $node->attribute('node_id'); $offset = 0; $subtreeCount = $node->subTreeCount(array('Limitation' => array(), 'MainNodeOnly' => true)); // While $offset < subtree count, loop through the nodes. while ($offset < $subtreeCount) { // Loop trough the available processes, and see if any has finished. for ($i = 0; $i < $processLimit; $i++) { $pid = $processList[$i]; if ($useFork) { if ($pid === -1 || !posix_kill($pid, 0)) { $newPid = $this->forkAndExecute($nodeID, $offset, $this->Limit); $this->CLI->output("\n" . 'Creating a new thread: ' . $newPid); if ($newPid > 0) { $offset += $this->Limit; $this->iterate(); $processList[$i] = $newPid; } else { $this->CLI->error("\n" . 'Returned invalid PID: ' . $newPid); } } } else { // Execute in same process $count = $this->execute($nodeID, $offset, $this->Limit); $this->iterate($count); $offset += $this->Limit; } if ($offset >= $subtreeCount) { break; } } // If using fork, the main process must sleep a bit to avoid // 100% cpu usage. Sleep for 100 millisec. if ($useFork) { $status = 0; pcntl_wait($status, WNOHANG); usleep(100000); } } } // Wait for all processes to finish. $break = false; while ($useFork && !$break) { $break = true; for ($i = 0; $i < $processLimit; $i++) { $pid = $processList[$i]; if ($pid !== -1) { // Check if process is still alive. if (posix_kill($pid, 0)) { $break = false; } else { $this->CLI->output('Process finished: ' . $pid); $processList[$i] = -1; } } } // Sleep for 500 msec. $status = 0; pcntl_wait($status, WNOHANG); usleep(500000); } $this->CLI->output('Optimizing. Please wait ...'); $searchEngine->optimize(true); $endTS = microtime_float(); $this->CLI->output('Indexing took ' . ($endTS - $startTS) . ' secs ' . '( average: ' . $this->ObjectCount / ($endTS - $startTS) . ' objects/sec )'); $this->CLI->output('Finished updating the search index.'); }
/** * Iterate index counter * * @param int $count */ protected function iterate($count = false) { if (!$count) { $count = $this->Limit; } for ($iterateCount = 0; $iterateCount < $count; ++$iterateCount) { if (++$this->IterateCount > $this->ObjectCount) { break; } $this->Script->iterate($this->CLI, true); if ($this->IterateCount % 1000 === 0) { $this->CLI->output("\n" . 'Comitting and optimizing index ...'); $searchEngine = new eZSolr(); $searchEngine->optimize(); eZContentObject::clearCache(); } } }