Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync Aoe_Scheduler with AOE's repo #18

Merged
merged 7 commits into from
Jul 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
674 changes: 674 additions & 0 deletions LICENSE.txt

Large diffs are not rendered by default.

47 changes: 46 additions & 1 deletion app/code/local/Aoe/Scheduler/Model/Observer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ public function dispatch($observer)
$schedules = $this->getPendingSchedules();
$scheduleLifetime = Mage::getStoreConfig(self::XML_PATH_SCHEDULE_LIFETIME) * 60;
$now = time();
$jobsRoot = Mage::getConfig()->getNode('crontab/jobs');

// fetch global cronjob config
$jobsRoot = Mage::getConfig()->getNode('crontab/jobs');

// extend cronjob config with the configurable ones
$jobsRoot->extend(
Mage::getConfig()->getNode('default/crontab/jobs')
);

foreach ($schedules->getIterator() as $schedule) { /* @var $schedule Aoe_Scheduler_Model_Schedule */
try {
Expand Down Expand Up @@ -82,6 +89,8 @@ public function dispatch($observer)
$messages = var_export($messages, 1);
}
$schedule->setMessages($messages);
} else {
$messages = '';
}

if (strtoupper(substr($messages, 0, 6)) != 'ERROR:') {
Expand Down Expand Up @@ -185,4 +194,40 @@ public function generate() {
return $result;
}

public function getWhitelist() {
$whitelist = array();
if(getenv("SCHEDULER_WHITELIST") !== FALSE ) {
$whitelist = explode(',',getenv("SCHEDULER_WHITELIST"));
}
return $whitelist;
}

public function getBlacklist() {
$blacklist = array();
if(getenv("SCHEDULER_BLACKLIST") !== FALSE) {
$blacklist = explode(',',getenv("SCHEDULER_BLACKLIST"));
}
return $blacklist;
}

public function getPendingSchedules()
{
if (!$this->_pendingSchedules) {
$this->_pendingSchedules = Mage::getModel('cron/schedule')->getCollection()
->addFieldToFilter('status', Mage_Cron_Model_Schedule::STATUS_PENDING);

$whitelist = $this->getWhitelist();
if(!empty($whitelist)) {
$this->_pendingSchedules->addFieldToFilter('job_code', array('in'=> $whitelist));
}

$blacklist = $this->getBlacklist();
if(!empty($blacklist)) {
$this->_pendingSchedules->addFieldToFilter('job_code', array('nin'=> $blacklist));
}

$this->_pendingSchedules = $this->_pendingSchedules->load();
}
return $this->_pendingSchedules;
}
}
18 changes: 18 additions & 0 deletions app/code/local/Aoe/Scheduler/Model/Schedule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* @method string getCreatedAt()
* @method string getScheduledAt()
* @method string getJobCode()
* @method string setJobCode()
* @method string getParameters()
* @method string setParameters()
*/
class Aoe_Scheduler_Model_Schedule extends Mage_Cron_Model_Schedule {

Expand All @@ -16,6 +19,8 @@ class Aoe_Scheduler_Model_Schedule extends Mage_Cron_Model_Schedule {
*/
protected $_jobConfiguration;

protected $jobWasLocked = false;


/**
* Run this task now
Expand Down Expand Up @@ -44,8 +49,10 @@ public function runNow($tryLockJob=true) {

// lock job requires the record to be saved and having status Mage_Cron_Model_Schedule::STATUS_PENDING
// workaround could be to do this: $this->setStatus(Mage_Cron_Model_Schedule::STATUS_PENDING)->save();
$this->jobWasLocked = false;
if ($tryLockJob && !$this->tryLockJob()) {
// another cron started this job intermittently, so skip it
$this->jobWasLocked = true;
return $this;
}
$this->setExecutedAt(strftime('%Y-%m-%d %H:%M:%S', time()));
Expand Down Expand Up @@ -75,6 +82,17 @@ public function runNow($tryLockJob=true) {



/**
* Flag that shows that a previous execution was prevented because the job was locked
*
* @return bool
*/
public function getJobWasLocked() {
return $this->jobWasLocked;
}



/**
* Schedule this task to be executed as soon as possible
*
Expand Down
14 changes: 13 additions & 1 deletion app/code/local/Aoe/Scheduler/etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<config>
<modules>
<Aoe_Scheduler>
<version>0.2.2</version>
<version>0.1.0</version>
</Aoe_Scheduler>
</modules>

Expand Down Expand Up @@ -31,6 +31,18 @@
</rewrite>
</cron>
</models>

<resources>
<aoescheduler_setup>
<setup>
<module>Aoe_Scheduler</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</aoescheduler_setup>
</resources>

</global>

<admin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

$installer = $this; /* @var $installer Mage_Core_Model_Resource_Setup */

$installer->startSetup();
$installer->getConnection()->addColumn(
$installer->getTable('cron_schedule'),
'parameters',
"TEXT NULL COMMENT 'Serialized Parameters'"
);
$installer->endSetup();
16 changes: 16 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "aoepeople/aoe_scheduler",
"license": "GPLv3",
"type": "magento-module",
"description": "Running multiple scheduler jobs in parallel",
"homepage": "https://github.com/AOEpeople/Aoe_Scheduler",
"authors": [
{
"name": "Fabrizio Branca",
"email": "fabrizio.branca@aoe.com"
}
],
"require": {
"magento-hackathon/magento-composer-installer": "*"
}
}
22 changes: 22 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
AOE Scheduler for Magento
=========================
see http://www.fabrizio-branca.de/magento-cron-scheduler.html

Running multiple scheduler jobs in parallel
-------------------------------------------
Running multiple scheduler jobs in parallel is quite handy when you have some jobs which take a long time to run,
and are not crucial for shop to run properly. En excample could be a job which generates some kind of reports.
Magento cron.sh script detects if there is some job already running by parsing output of "ps" command.
If not, it executes cron.php file.
So to run multiple schedulers in parallel we have to use different file name than cron.php.
Additionally we want to run only few jobs with second cron task, and exclude them from the original scheduler job.
Aoe Scheduler comes with whitelist/blacklist feature enabling you to do so.

1. symlink cron.php to cron2.php
2. add crontab configuration (crontab -e) like this:

* * * * * /usr/bin/env SCHEDULER_BLACKLIST='job_key1,job_key2' /bin/sh /home/webapps/htdocs/cron.sh
* * * * * /usr/bin/env SCHEDULER_WHITELIST='job_key1,job_key2' /bin/sh /home/webapps/htdocs/cron.sh cron2.php

cron.sh script takes name of the php script to run as a parameter (by default it is cron.php).
This way the first cron job will execute all scheduler jobs except job_key1 and job_key2, and the second one will execute only them.
8 changes: 6 additions & 2 deletions shell/scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public function scheduleNowAction() {
}
$schedule = Mage::getModel('cron/schedule'); /* @var $schedule Aoe_Scheduler_Model_Schedule */
$schedule->setJobCode($code);
$schedule->scheduleNow();
$schedule->schedule();
$schedule->save();
}

Expand Down Expand Up @@ -156,7 +156,11 @@ public function runNowAction() {
}
$schedule = Mage::getModel('cron/schedule'); /* @var $schedule Aoe_Scheduler_Model_Schedule */
$schedule->setJobCode($code);
$schedule->runNow();
$schedule->runNow(false);
if ($schedule->getJobWasLocked()) {
echo "\nJob was not executed because it was locked!\n\n";
exit(1);
}
$schedule->save();
}

Expand Down