diff --git a/.htaccess b/.htaccess index 2998f48f7addce87c68296ed33d68837bd439b6b..404488eb7ff0ecc6197ab8c100555c79eb1cf0ce 100644 --- a/.htaccess +++ b/.htaccess @@ -1,3 +1,8 @@ +############################################ +## uncomment the line below to enable developer mode + +# SetEnv MAGE_MODE developer + ############################################ ## uncomment these lines for CGI mode ## make sure to specify the correct cgi php binary file name @@ -167,6 +172,8 @@ ## http://developer.yahoo.com/performance/rules.html#expires ExpiresDefault "access plus 1 year" + ExpiresByType text/html A0 + ExpiresByType text/plain A0 </IfModule> diff --git a/.htaccess.sample b/.htaccess.sample index 3a19430211147f23f6e460addf435d771380b944..133ce7de2c59badd5df4a159bb921e8a99f05eb7 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -1,3 +1,8 @@ +############################################ +## uncomment the line below to enable developer mode + +# SetEnv MAGE_MODE developer + ############################################ ## uncomment these lines for CGI mode ## make sure to specify the correct cgi php binary file name @@ -164,6 +169,8 @@ ## http://developer.yahoo.com/performance/rules.html#expires ExpiresDefault "access plus 1 year" + ExpiresByType text/html A0 + ExpiresByType text/plain A0 </IfModule> diff --git a/app/code/Magento/Cron/Model/Observer.php b/app/code/Magento/Cron/Model/Observer.php index 0c4330b236445e5158ced871f4c4de452a4d53e4..800e1e732710d455b0a12a728df25a01f486ba5f 100644 --- a/app/code/Magento/Cron/Model/Observer.php +++ b/app/code/Magento/Cron/Model/Observer.php @@ -345,6 +345,13 @@ class Observer return $this; } + // check how long the record should stay unprocessed before marked as MISSED + $scheduleLifetime = (int)$this->_scopeConfig->getValue( + 'system/cron/' . $groupId . '/' . self::XML_PATH_SCHEDULE_LIFETIME, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + $scheduleLifetime = $scheduleLifetime * self::SECONDS_IN_MINUTE; + /** * @var \Magento\Cron\Model\Resource\Schedule\Collection $history */ @@ -370,7 +377,9 @@ class Observer $now = $this->timezone->scopeTimeStamp(); /** @var Schedule $record */ foreach ($history as $record) { - if (strtotime($record->getExecutedAt()) < $now - $historyLifetimes[$record->getStatus()]) { + $checkTime = $record->getExecutedAt() ? strtotime($record->getExecutedAt()) : + strtotime($record->getScheduledAt()) + $scheduleLifetime; + if ($checkTime < $now - $historyLifetimes[$record->getStatus()]) { $record->delete(); } } diff --git a/app/code/Magento/Cron/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Cron/Test/Unit/Model/ObserverTest.php index 1b9c5cd798101a15d4fd8ab122dacc1afa67bba0..1f67cb67065623e9bc84a9e41c12baa9bb4a8ae7 100644 --- a/app/code/Magento/Cron/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Cron/Test/Unit/Model/ObserverTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Cron\Test\Unit\Model; +use Magento\Cron\Model\Schedule; + /** * Class \Magento\Cron\Test\Unit\Model\ObserverTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -607,4 +609,84 @@ class ObserverTest extends \PHPUnit_Framework_TestCase $this->_observer->dispatch(''); } + + public function testMissedJobsCleanedInTime() + { + /* 1. Initialize dependencies of _generate() method which is called first */ + $jobConfig = [ + 'test_group' => ['test_job1' => ['instance' => 'CronJob', 'method' => 'execute']], + ]; + + // This item was scheduled 2 days ago + $schedule1 = $this->getMockBuilder( + 'Magento\Cron\Model\Schedule' + )->disableOriginalConstructor()->setMethods( + ['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup'] + )->getMock(); + $schedule1->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null)); + $schedule1->expects($this->any())->method('getScheduledAt')->will($this->returnValue('-2 day -1 hour')); + $schedule1->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED)); + //we expect this job be deleted from the list + $schedule1->expects($this->once())->method('delete')->will($this->returnValue(true)); + + // This item was scheduled 1 day ago + $schedule2 = $this->getMockBuilder( + 'Magento\Cron\Model\Schedule' + )->disableOriginalConstructor()->setMethods( + ['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup'] + )->getMock(); + $schedule2->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null)); + $schedule2->expects($this->any())->method('getScheduledAt')->will($this->returnValue('-1 day')); + $schedule2->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED)); + //we don't expect this job be deleted from the list + $schedule2->expects($this->never())->method('delete'); + + $this->_collection->addItem($schedule1); + $this->_config->expects($this->once())->method('getJobs')->will($this->returnValue($jobConfig)); + + //get configuration value CACHE_KEY_LAST_HISTORY_CLEANUP_AT in the "_generate()" + $this->_cache->expects($this->at(0))->method('load')->will($this->returnValue(time() + 10000000)); + //get configuration value CACHE_KEY_LAST_HISTORY_CLEANUP_AT in the "_cleanup()" + $this->_cache->expects($this->at(1))->method('load')->will($this->returnValue(time() - 10000000)); + + $this->_scopeConfig->expects($this->at(0))->method('getValue') + ->with($this->equalTo('system/cron/test_group/use_separate_process')) + ->will($this->returnValue(0)); + $this->_scopeConfig->expects($this->at(1))->method('getValue') + ->with($this->equalTo('system/cron/test_group/schedule_generate_every')) + ->will($this->returnValue(0)); + $this->_scopeConfig->expects($this->at(2))->method('getValue') + ->with($this->equalTo('system/cron/test_group/history_cleanup_every')) + ->will($this->returnValue(0)); + $this->_scopeConfig->expects($this->at(3))->method('getValue') + ->with($this->equalTo('system/cron/test_group/schedule_lifetime')) + ->will($this->returnValue(2*24*60)); + $this->_scopeConfig->expects($this->at(4))->method('getValue') + ->with($this->equalTo('system/cron/test_group/history_success_lifetime')) + ->will($this->returnValue(0)); + $this->_scopeConfig->expects($this->at(5))->method('getValue') + ->with($this->equalTo('system/cron/test_group/history_failure_lifetime')) + ->will($this->returnValue(0)); + + /* 2. Initialize dependencies of _cleanup() method which is called second */ + $scheduleMock = $this->getMockBuilder('Magento\Cron\Model\Schedule')->disableOriginalConstructor()->getMock(); + $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection)); + $this->_scheduleFactory->expects($this->at(0))->method('create')->will($this->returnValue($scheduleMock)); + + $collection = $this->getMockBuilder( + 'Magento\Cron\Model\Resource\Schedule\Collection' + )->setMethods( + ['addFieldToFilter', 'load', '__wakeup'] + )->disableOriginalConstructor()->getMock(); + $collection->expects($this->any())->method('addFieldToFilter')->will($this->returnSelf()); + $collection->expects($this->any())->method('load')->will($this->returnSelf()); + $collection->addItem($schedule1); + $collection->addItem($schedule2); + + $scheduleMock = $this->getMockBuilder('Magento\Cron\Model\Schedule')->disableOriginalConstructor()->getMock(); + $scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($collection)); + $this->_scheduleFactory->expects($this->at(1))->method('create')->will($this->returnValue($scheduleMock)); + + $this->_observer->dispatch(''); + } } diff --git a/dev/tests/functional/.htaccess b/dev/tests/functional/.htaccess index db0b8f66ad0008c5f765391d0b93515d711ab1b7..0fe8af43b87597383c5904481c15b751e52630d2 100644 --- a/dev/tests/functional/.htaccess +++ b/dev/tests/functional/.htaccess @@ -170,6 +170,8 @@ ## http://developer.yahoo.com/performance/rules.html#expires ExpiresDefault "access plus 1 year" + ExpiresByType text/html A0 + ExpiresByType text/plain A0 </IfModule> @@ -191,4 +193,4 @@ ## If running in cluster environment, uncomment this ## http://developer.yahoo.com/performance/rules.html#etags - #FileETag none \ No newline at end of file + #FileETag none diff --git a/nginx.conf.sample b/nginx.conf.sample index 1ea8ee9e97f28f40107edb14b4fe53e66589b40a..2ea2b6ce5848867deae4c3c6287234706039e57f 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -127,6 +127,7 @@ location / { } location ~ (index|get|static|report|404|503)\.php$ { + expires -1; fastcgi_pass fastcgi_backend; fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; diff --git a/pub/.htaccess b/pub/.htaccess index b3f9b82f3723b106829e136d1609134ed4fdc196..7cac070b85bf7b33c187cfcefd3bf6e8e456306b 100755 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -1,3 +1,8 @@ +############################################ +## uncomment the line below to enable developer mode + +# SetEnv MAGE_MODE developer + ############################################ ## uncomment these lines for CGI mode ## make sure to specify the correct cgi php binary file name @@ -153,6 +158,8 @@ ## http://developer.yahoo.com/performance/rules.html#expires ExpiresDefault "access plus 1 year" + ExpiresByType text/html A0 + ExpiresByType text/plain A0 </IfModule>