/** * Tells the core indexer to do a partial reindex * @param Mage_Index_Model_Process $process * @throws Exception */ public function executePartialIndex(Mage_Index_Model_Process $process) { /** @var $resourceModel Mage_Index_Model_Resource_Process */ $resourceModel = Mage::getResourceSingleton('index/process'); if (Mage::getStoreConfigFlag('system/asyncindex/use_transactions')) { $resourceModel->beginTransaction(); } $indexMode = 'schedule'; $pendingMode = 'pending'; //Fallback for 1.6.2 installations > Undefined class constant 'MODE_SCHEDULE' if (true === defined('Mage_Index_Model_Process::MODE_SCHEDULE')) { $indexMode = Mage_Index_Model_Process::MODE_SCHEDULE; $pendingMode = Mage_Index_Model_Process::STATUS_PENDING; } try { $process->setMode($indexMode); $process->indexEvents(); if (count(Mage::getResourceSingleton('index/event')->getUnprocessedEvents($process)) === 0) { $process->changeStatus($pendingMode); } if (Mage::getStoreConfigFlag('system/asyncindex/use_transactions')) { $resourceModel->commit(); } } catch (Exception $e) { if (Mage::getStoreConfigFlag('system/asyncindex/use_transactions')) { $resourceModel->rollBack(); } throw $e; } }
public function start($count = 0) { if (!$count) { $this->limit = Mage::getStoreConfig('kirchbergerknorr/factfindersync/queue'); } else { $this->limit = $count; } if ($this->indexProcess->isLocked()) { $this->log("Another %s process is running! Aborted", self::PROCESS_ID); return false; } // Set an exclusive lock. $this->indexProcess->lockAndBlock(); $this->log("========================================"); $timeStart = microtime(true); $this->log("Started FactFinderSync"); $this->insertNewProducts(); $this->updateImportedProducts(); $timeEnd = microtime(true); $time = $timeEnd - $timeStart; $this->log("Finished FactFinderSync limit %s in %s seconds", $this->limit, $time); // Remove the lock. $this->indexProcess->unlock(); return true; }
/** * Add filter by process and status to events collection * * @param int|array|Mage_Index_Model_Process $process * @param string $status * @return Mage_Index_Model_Resource_Event_Collection */ public function addProcessFilter($process, $status = null) { $this->_joinProcessEventTable(); if ($process instanceof Mage_Index_Model_Process) { $this->addFieldToFilter('process_event.process_id', $process->getId()); } elseif (is_array($process) && !empty($process)) { $this->addFieldToFilter('process_event.process_id', array('in' => $process)); } else { $this->addFieldToFilter('process_event.process_id', $process); } if ($status !== null) { $this->addFieldToFilter('process_event.status', $status); } return $this; }
/** * Reindex all data what this process responsible is * Check and using depends processes * * @return Mage_Index_Model_Process */ public function reindexEverything($force = false) { parent::reindexEverything(); if ($force) { return $this->reindexAll(true); } }
/** * @dataProvider isLockedDataProvider * @param bool $needUnlock */ public function testIsLocked($needUnlock) { $this->_processFile = $this->getMock('Mage_Index_Model_Process_File', array('isProcessLocked')); $this->_processFile->expects($this->once())->method('isProcessLocked')->with($needUnlock)->will($this->returnArgument(0)); $this->_prepareIndexProcess(); $this->assertEquals($needUnlock, $this->_indexProcess->isLocked($needUnlock)); }
/** * Process event with locks checking - this function is overridden to prevent Magento from indexing event while saving product * * @param Mage_Index_Model_Event $event * @return Mage_Index_Model_Process */ public function safeProcessEvent(Mage_Index_Model_Event $event) { if ($this->getMode() == self::MODE_QUEUED) { return $this; } else { return parent::processEvent($event); } }
/** * Add mass-actions to grid * * @return Mage_Index_Block_Adminhtml_Process_Grid */ protected function _prepareMassaction() { $this->setMassactionIdField('process_id'); $this->getMassactionBlock()->setFormFieldName('process'); $this->getMassactionBlock()->addItem('change_mode', array('label' => Mage::helper('enterprise_index')->__('Change Index Mode'), 'url' => $this->getUrl('*/*/massChangeMode'), 'additional' => array('mode' => array('name' => 'index_mode', 'type' => 'select', 'class' => 'required-entry', 'label' => Mage::helper('enterprise_index')->__('Index mode'), 'values' => $this->_processModel->getModesOptions())))); $this->getMassactionBlock()->addItem('reindex', array('label' => Mage::helper('enterprise_index')->__('Reindex Data'), 'url' => $this->getUrl('*/*/massReindex'), 'selected' => true)); return $this; }
/** * Renders progress bar with estimated time (for running process) * * @param Mage_Index_Model_Process $process * @return string */ protected function _renderProgress(Mage_Index_Model_Process $process) { $progressBarId = 'hackathon_indexerstats_progress_' . $process->getIndexerCode(); $progress = min(100, $this->_runtimeModel->getProgress($process) * 100); if ($this->_runtimeModel->getProgress($process) >= 1) { $inTimeClass = 'hackathon_indexerstats_not_in_time'; $timeCaption = Mage::helper('hackathon_indexerstats')->__('over time'); } else { $inTimeClass = 'hackathon_indexerstats_in_time'; $timeCaption = Mage::helper('hackathon_indexerstats')->__('remaining'); } $now = date_create()->getTimestamp(); $startTimestamp = $this->_runtimeModel->getStartTime($process)->getTimestamp(); $estimatedEndTimestamp = $this->_runtimeModel->getEstimatedEndTime($process)->getTimestamp(); $timeDisplay = $this->_runtimeModel->getRemainingTime($process); return <<<HTML <div id="{$progressBarId}" data-now="{$now}" data-started="{$startTimestamp}" data-estimated_end="{$estimatedEndTimestamp}" class="hackathon_indexerstats_info hackathon_indexerstats_progress {$inTimeClass}"> <span style="width: {$progress}%;"><span></span></span> <div><span class="hackathon_indexerstats_time_display">{$timeDisplay}</span> <span class="hackathon_indexerstats_time_caption">{$timeCaption}</span></div> </div> HTML; }
/** * Set start time and end time based on current process data * * @param Mage_Index_Model_Process $process * @return $this */ public function setDataFromProcess(Mage_Index_Model_Process $process) { $startTime = new DateTime($process->getStartedAt()); $endTime = new DateTime($process->getEndedAt()); $runningTime = $endTime->getTimestamp() - $startTime->getTimestamp(); $this->setData(array('process_id' => $process->getId(), 'started_at' => $process->getStartedAt(), 'ended_at' => $process->getEndedAt(), 'running_time' => $runningTime)); return $this; }
public function testSafeProcessEventException() { // prepare mock that throws exception /** @var $eventMock Mage_Index_Model_Event */ $eventMock = $this->getMock('Mage_Index_Model_Event', array('setProcess'), array(), '', false); $eventMock->setData($this->_indexerMatchData); $exceptionMessage = self::EXCEPTION_MESSAGE; $eventMock->expects($this->any())->method('setProcess')->will($this->returnCallback(function () use($exceptionMessage) { throw new Exception($exceptionMessage); })); // can't use @expectedException because we need to assert indexer lock status try { $this->_model->safeProcessEvent($eventMock); } catch (Exception $e) { $this->assertEquals(self::EXCEPTION_MESSAGE, $e->getMessage()); } $this->assertFalse($this->_processFile->isProcessLocked(true)); }
/** * Decorate "Update Required" column values * * @param string $value * @param Mage_Index_Model_Process $row * @param Mage_Adminhtml_Block_Widget_Grid_Column $column * @param bool $isExport * @return string */ public function decorateUpdateRequired($value, $row, $column, $isExport) { $class = ''; switch ($row->getUpdateRequired()) { case 0: $class = 'grid-severity-notice'; break; case 1: $class = 'grid-severity-critical'; break; } return '<span class="' . $class . '"><span>' . $value . '</span></span>'; }
/** * Update process end date * * @param Mage_Index_Model_Process $process * @return Mage_Index_Model_Resource_Process */ public function updateProcessEndDate(Mage_Index_Model_Process $process) { $this->_updateProcessData($process->getId(), array('ended_at' => $this->formatDate(time()))); return $this; }
/** * Register process start * * @param Mage_Index_Model_Process $process * @return Mage_Index_Model_Mysql4_Process */ public function startProcess(Mage_Index_Model_Process $process) { $data = array('status' => Mage_Index_Model_Process::STATUS_RUNNING, 'started_at' => $this->formatDate(time())); $this->_getWriteAdapter()->update($this->getMainTable(), $data, $this->_getWriteAdapter()->quoteInto('process_id=?', $process->getId())); return $this; }
/** * Update process status field * * * @param Mage_Index_Model_Process $process * @param string $status * @return Mage_Index_Model_Resource_Process */ public function updateStatus($process, $status) { $data = array('status' => $status); $this->_updateProcessData($process->getId(), $data); return $this; }
/** * Check if the event will be processed and disable/enable keys in index tables * * @param mixed|Mage_Index_Model_Process $process * @param bool $enable * @return bool */ protected function _changeProcessKeyStatus($process, $enable = true) { $event = $this->_currentEvent; if ($process instanceof Mage_Index_Model_Process && $process->getMode() !== Mage_Index_Model_Process::MODE_MANUAL && !$process->isLocked() && (is_null($event) || $event instanceof Mage_Index_Model_Event && $process->matchEvent($event) || is_array($event) && $process->matchEntityAndType($event[0], $event[1]))) { if ($enable) { $process->enableIndexerKeys(); } else { $process->disableIndexerKeys(); } return true; } return false; }
/** * Retrieve unprocessed events list by specified process * * @param Mage_Index_Model_Process $process * @return array */ public function getUnprocessedEvents($process) { $select = $this->_getReadAdapter()->select()->from($this->getTable('index/process_event'))->where('process_id = ?', $process->getId())->where('status = ?', Mage_Index_Model_Process::EVENT_STATUS_NEW); return $this->_getReadAdapter()->fetchAll($select); }
/** * Get row edit url * * @param Mage_Index_Model_Process $row * * @return string */ public function getRowUrl($row) { return $this->getUrl('*/*/edit', array('process' => $row->getId())); }
/** * Check if process is locked * * @return bool */ public function isLocked() { if (false === $this->getLockInstance()) { return parent::isLocked(); } return $this->getLockInstance()->isLocked(); }
/** * Run the Task * * IF ANY Job we run fails, due to another processes being run we should * gracefully exit and wait our next go! * * Also change auto sync to just create a job, and run a single job Queue! */ public function run() { if ($this->_config()->isLogEnabled()) { $this->_config()->dbLog("Cron [Triggered]"); } /** * This doesn't exist in 1.3.2! */ $indexProcess = new Mage_Index_Model_Process(); $indexProcess->setId(self::LOCK_INDEX_ID); if ($indexProcess->isLocked()) { // Check how old the lock is - unlock after 1hr if ($this->_lockIsOld(self::LOCK_INDEX_ID)) { $indexProcess->unlock(); } else { $this->_config()->log('MAILUP: cron already running or locked'); return false; } } $indexProcess->lockAndBlock(); try { require_once dirname(__FILE__) . '/../Helper/Data.php'; $db_read = Mage::getSingleton('core/resource')->getConnection('core_read'); $db_write = Mage::getSingleton('core/resource')->getConnection('core_write'); $syncTableName = Mage::getSingleton('core/resource')->getTableName('mailup/sync'); $jobsTableName = Mage::getSingleton('core/resource')->getTableName('mailup/job'); $lastsync = gmdate("Y-m-d H:i:s"); // reading customers (jobid == 0, their updates) $customer_entity_table_name = Mage::getSingleton('core/resource')->getTableName('customer_entity'); /** * Now Handle Jobs we need to Sync, and all customers attached to each job */ foreach (Mage::getModel('mailup/job')->fetchQueuedOrStartedJobsCollection() as $jobModel) { /* @var $jobModel MailUp_MailUpSync_Model_Job */ $job = $jobModel->getData(); $storeId = isset($job['store_id']) ? $job['store_id'] : NULL; // If job is auto-sync and cron is not enabled for the job's site, skip the job if ($jobModel->isAutoSync() && !$this->_config()->isCronExportEnabled($storeId)) { $this->_config()->dbLog("Auto-Task skipped as auto-sync disabled for site", $job["id"], $storeId); continue; } $stmt = $db_write->query("UPDATE {$jobsTableName}\n SET status='started', start_datetime='" . gmdate("Y-m-d H:i:s") . "'\n WHERE id={$job["id"]}"); $customers = array(); $job['mailupNewGroup'] = 0; $job['mailupIdList'] = Mage::getStoreConfig('mailup_newsletter/mailup/list', $storeId); $job["mailupGroupId"] = $job["mailupgroupid"]; $job["send_optin_email_to_new_subscribers"] = $job["send_optin"]; // If group is 0 and there is a default group, set group to this group $defaultGroupId = Mage::getStoreConfig('mailup_newsletter/mailup/default_group'); if ($job["mailupGroupId"] == 0 && $defaultGroupId !== null) { $job["mailupGroupId"] = $defaultGroupId; } $tmp = Mage::getSingleton('mailup/source_lists'); $tmp = $tmp->toOptionArray($storeId); // pass store id! foreach ($tmp as $t) { if ($t["value"] == $job['mailupIdList']) { $job['mailupListGUID'] = $t["guid"]; $job["groups"] = $t["groups"]; break; } } unset($tmp); unset($t); $stmt = $db_read->query("\n SELECT ms.*, ce.email\n FROM {$syncTableName} ms\n JOIN {$customer_entity_table_name} ce\n ON (ms.customer_id = ce.entity_id)\n WHERE ms.needs_sync=1\n AND ms.entity='customer'\n AND job_id={$job["id"]}"); while ($row = $stmt->fetch()) { $customers[] = $row["customer_id"]; } /** * Send the Data! */ $returnCode = MailUp_MailUpSync_Helper_Data::generateAndSendCustomers($customers, $job, $storeId); /** * Check return OK */ if ($returnCode === 0) { $customerCount = count($customers); $db_write->query("\n UPDATE {$syncTableName} SET needs_sync=0, last_sync='{$lastsync}'\n WHERE job_id = {$job["id"]}\n AND entity='customer'"); $this->_config()->dbLog("Job Task [update] [Synced] [customer count:{$customerCount}]", $job["id"], $storeId); // finishing the job also $db_write->query("\n UPDATE {$jobsTableName} SET status='finished', finish_datetime='" . gmdate("Y-m-d H:i:s") . "'\n WHERE id={$job["id"]}"); $this->_config()->dbLog("Jobs [Update] [Complete] [{$job["id"]}]", $job["id"], $storeId); } else { $stmt = $db_write->query("UPDATE {$jobsTableName} SET status='queued' WHERE id={$job["id"]}"); if ($this->_config()->isLogEnabled()) { $this->_config()->dbLog(sprintf("generateAndSendCustomers [ReturnCode] [ERROR] [%d]", $returnCode), $job["id"], $storeId); } } } } catch (Exception $e) { // In case of otherwise uncaught error, unlock and re-throw $indexProcess->unlock(); throw $e; } $indexProcess->unlock(); if ($this->_config()->isLogEnabled()) { $this->_config()->dbLog("Cron [Completed]"); } }
public function getProgress(Mage_Index_Model_Process $process) { $avgTime = Mage::getModel('hackathon_indexerstats_resource/history')->getAvg($process->getId()); $currentTime = new DateTime(); $startTime = new DateTime($process->getStartedAt()); $estimatedEndTime = new DateTime($process->getStartedAt()); $estimatedEndTime->add(new DateInterval('PT' . $avgTime . 'S')); $processDiff = $currentTime->getTimestamp() - $startTime->getTimestamp(); if ($avgTime == 0) { return 1; } return $processDiff / $avgTime; }
/** * @param Mage_Index_Model_Process $process * * @throws Exception */ protected function _execPartialIndex(Mage_Index_Model_Process $process) { $this->_indexerTransactionBegin(); // MODE_SCHEDULE available in Mage >1.8 $indexMode = true === defined('Mage_Index_Model_Process::MODE_SCHEDULE') ? Mage_Index_Model_Process::MODE_SCHEDULE : 'schedule'; $pendingMode = Mage_Index_Model_Process::STATUS_PENDING; try { $process->setMode($indexMode); $process->indexEvents(); $unProcessedEvents = count(Mage::getResourceSingleton('index/event')->getUnprocessedEvents($process)); if (0 === $unProcessedEvents) { $process->changeStatus($pendingMode); } $this->_indexerTransactionCommit(); } catch (Exception $e) { $this->_indexerTransactionRollBack(); throw $e; } }
* NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/osl-3.0.php * * @category Mehulchaudhari * @package Mehulchaudhari_FeedsGenerator * @author Mehul Chaudhari * @copyright Copyright (c) 2014 ; ; * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** @var $installer Mage_Eav_Model_Entity_Setup */ const PROCESS_ID = 'google_taxonomy'; $indexProcess = new Mage_Index_Model_Process(); $indexProcess->setId(PROCESS_ID); if (!$indexProcess->isLocked()) { $indexProcess->lockAndBlock(); $installer = $this; $installer->startSetup(); // Create (or re-create) the table containing all of the Google taxonomy information. This is a list // of available taxonomy values. $installer->run("\n DROP TABLE IF EXISTS {$this->getTable('feedsgenerator_taxonomy')};\n CREATE TABLE {$this->getTable('feedsgenerator_taxonomy')} (\n `taxonomy_id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n\t\t `store_lang` varchar(255) NOT NULL,\n `taxonomy_name` varchar(255) NOT NULL,\n PRIMARY KEY (`taxonomy_id`)\n ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n "); // Fill the taxonomy table with values provided by Google. Values are inserted in batches of // 1000 to increase processing speed. $connection = $installer->getConnection(); $Datail = Mage::getModel('feedsgenerator/googleproducts_taxonomy')->getDataDetail(); foreach ($Datail as $lang => $taxonomy) { $data = array(); foreach ($taxonomy as $i => $t) {