Skip to content

Commit 4f9bc56

Browse files
author
Ethan Yehuda
authored
Merge pull request #112 from Ethan3600/1.x-develop
Release v1.8.0
2 parents 468c219 + 59f005b commit 4f9bc56

40 files changed

+1134
-190
lines changed

.travis.yml

+1-9
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,7 @@ matrix:
3131
- TEST_SUITE=integration
3232
- php: 7.1
3333
env:
34-
- MAGENTO_VERSION=2.2.2
35-
- TEST_SUITE=integration
36-
- php: 7.0
37-
env:
38-
- MAGENTO_VERSION=2.2-develop
39-
- TEST_SUITE=integration
40-
- php: 7.0
41-
env:
42-
- MAGENTO_VERSION=2.2.2
34+
- MAGENTO_VERSION=2.2
4335
- TEST_SUITE=integration
4436
env:
4537
global:

.travis/before_script.sh

+24-4
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,28 @@ git clone --branch $MAGENTO_VERSION --depth=1 https://github.com/magento/magento
2323
cd magento2
2424

2525
# add composer package under test, composer require will trigger update/install
26-
composer config minimum-stability dev
27-
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
28-
composer require $COMPOSER_PACKAGE_NAME:$TRAVIS_BRANCH-dev#$TRAVIS_COMMIT
26+
case $TRAVIS_BRANCH in
27+
1.x)
28+
composer config minimum-stability dev
29+
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
30+
composer require ${COMPOSER_PACKAGE_NAME}:${TRAVIS_BRANCH}-dev\#{$TRAVIS_COMMIT}
31+
;;
32+
1.x-develop)
33+
composer config minimum-stability dev
34+
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
35+
composer require ${COMPOSER_PACKAGE_NAME}:dev-${TRAVIS_BRANCH}\#{$TRAVIS_COMMIT}
36+
;;
37+
0.x)
38+
composer config minimum-stability dev
39+
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
40+
composer require ${COMPOSER_PACKAGE_NAME}:${TRAVIS_BRANCH}-dev\#{$TRAVIS_COMMIT}
41+
;;
42+
0.x-develop)
43+
composer config minimum-stability dev
44+
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
45+
composer require ${COMPOSER_PACKAGE_NAME}:dev-${TRAVIS_BRANCH}\#{$TRAVIS_COMMIT}
46+
;;
47+
esac
2948

3049
# prepare for test suite
3150
case $TEST_SUITE in
@@ -39,7 +58,8 @@ case $TEST_SUITE in
3958
SET @@global.sql_mode = NO_ENGINE_SUBSTITUTION;
4059
CREATE DATABASE magento_integration_tests;
4160
'
42-
mv etc/install-config-mysql.travis.php.dist etc/install-config-mysql.php
61+
cp etc/install-config-mysql.travis.php.dist etc/install-config-mysql.php
62+
sed -i '/amqp/d' etc/install-config-mysql.php
4363

4464
cd ../../..
4565
;;

Api/Data/ScheduleInterface.php

+25
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,22 @@
22

33
namespace EthanYehuda\CronjobManager\Api\Data;
44

5+
use Magento\Cron\Model\Schedule;
6+
57
interface ScheduleInterface
68
{
9+
const STATUS_PENDING = Schedule::STATUS_PENDING;
10+
11+
const STATUS_RUNNING = Schedule::STATUS_RUNNING;
12+
13+
const STATUS_SUCCESS = Schedule::STATUS_SUCCESS;
14+
15+
const STATUS_MISSED = Schedule::STATUS_MISSED;
16+
17+
const STATUS_ERROR = Schedule::STATUS_ERROR;
18+
19+
const STATUS_KILLED = 'killed';
20+
721
/**
822
* @return int
923
*/
@@ -49,6 +63,11 @@ public function getExecutedAt();
4963
*/
5064
public function getFinishedAt();
5165

66+
/**
67+
* @return string|null
68+
*/
69+
public function getKillRequest();
70+
5271
/**
5372
* @param int $scheduleId
5473
* @return ScheduleInterface
@@ -102,4 +121,10 @@ public function setExecutedAt(string $executedAt): self;
102121
* @return ScheduleInterface
103122
*/
104123
public function setFinishedAt(string $finishedAt): self;
124+
125+
/**
126+
* @param string $killRequest
127+
* @return ScheduleInterface
128+
*/
129+
public function setKillRequest(string $killRequest): self;
105130
}

Api/ScheduleManagementInterface.php

+7
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,11 @@ public function schedule(string $jobCode, int $time): Schedule;
5454
* @return bool
5555
*/
5656
public function flush(): bool;
57+
58+
/**
59+
* @param int $jobId
60+
* @return bool
61+
*/
62+
public function kill(int $jobId, int $timestamp): bool;
63+
5764
}

Api/ScheduleRepositoryAdapterInterface.php

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace EthanYehuda\CronjobManager\Api;
44

5+
use EthanYehuda\CronjobManager\Api\Data\ScheduleInterface;
56
use Magento\Framework\Exception\CouldNotSaveException;
67
use Magento\Framework\Exception\NoSuchEntityException;
78

@@ -31,4 +32,12 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
3132
* @throws CouldNotSaveException
3233
*/
3334
public function save(\EthanYehuda\CronjobManager\Api\Data\ScheduleInterface $schedule, $scheduleId = null): \EthanYehuda\CronjobManager\Api\Data\ScheduleInterface;
35+
36+
/**
37+
* Return all jobs with given status
38+
*
39+
* @param string $status
40+
* @return ScheduleInterface[]
41+
*/
42+
public function getByStatus($status);
3443
}

Console/Command/Runjob.php

+21-46
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,27 @@
22

33
namespace EthanYehuda\CronjobManager\Console\Command;
44

5-
use EthanYehuda\CronjobManager\Model\ManagerFactory;
5+
use Magento\Framework\App\ObjectManagerFactory;
6+
use Magento\Store\Model\Store;
7+
use Magento\Store\Model\StoreManager;
68
use Symfony\Component\Console\Command\Command;
9+
use Symfony\Component\Console\Input\InputArgument;
710
use Symfony\Component\Console\Input\InputInterface;
811
use Symfony\Component\Console\Output\OutputInterface;
9-
use Symfony\Component\Console\Input\InputArgument;
10-
use Magento\Framework\App\Area;
11-
use Magento\Framework\App\State;
12-
use Magento\Framework\Console\Cli;
13-
use Magento\Framework\Stdlib\DateTime\DateTimeFactory;
1412

1513
class Runjob extends Command
1614
{
1715
const INPUT_KEY_JOB_CODE = 'job_code';
1816

1917
/**
20-
* @var ManagerFactory $managerFactory
21-
*/
22-
private $managerFactory;
23-
24-
/**
25-
* @var \Magento\Framework\App\State $state
18+
* @var ObjectManagerFactory
2619
*/
27-
private $state;
28-
29-
/**
30-
* @var DateTimeFactory $dateTimeFactory
31-
*/
32-
private $dateTimeFactory;
20+
private $objectManagerFactory;
3321

3422
public function __construct(
35-
State $state,
36-
ManagerFactory $managerFactory,
37-
DateTimeFactory $dateTimeFactory
23+
ObjectManagerFactory $objectManagerFactory
3824
) {
39-
$this->managerFactory = $managerFactory;
40-
$this->state = $state;
41-
$this->dateTimeFactory = $dateTimeFactory;
25+
$this->objectManagerFactory = $objectManagerFactory;
4226
parent::__construct();
4327
}
4428

@@ -60,27 +44,18 @@ protected function configure()
6044

6145
protected function execute(InputInterface $input, OutputInterface $output)
6246
{
63-
$manager = $this->managerFactory->create();
64-
$dateTime = $this->dateTimeFactory->create();
65-
66-
try {
67-
$this->state->setAreaCode(Area::AREA_ADMINHTML);
68-
} catch (\Magento\Framework\Exception\LocalizedException $exception) {
69-
// Area code is already set
70-
}
71-
72-
try {
73-
// lets create a new cron job and dispatch it
74-
$jobCode = $input->getArgument(self::INPUT_KEY_JOB_CODE);
75-
$now = strftime('%Y-%m-%dT%H:%M:%S', $dateTime->gmtTimestamp());
76-
77-
$schedule = $manager->createCronJob($jobCode, $now);
78-
$manager->dispatchCron(null, $jobCode, $schedule);
79-
$output->writeln("$jobCode successfully ran");
80-
return Cli::RETURN_SUCCESS;
81-
} catch (\Magento\Framework\Exception\LocalizedException $e) {
82-
$output->writeln($e->getMessage());
83-
return Cli::RETURN_FAILURE;
84-
}
47+
/**
48+
* @todo Find a way to avoid using `ObjectManager`
49+
*/
50+
$omParams = $_SERVER;
51+
$omParams[StoreManager::PARAM_RUN_CODE] = Store::ADMIN_CODE;
52+
$omParams[Store::CUSTOM_ENTRY_POINT_PARAM] = true;
53+
$objectManager = $this->objectManagerFactory->create($omParams);
54+
55+
$jobCode = $input->getArgument(self::INPUT_KEY_JOB_CODE);
56+
$cron = $objectManager->create(\EthanYehuda\CronjobManager\Model\Cron\Runner::class);
57+
list($resultCode, $resultMessage) = $cron->runCron($jobCode);
58+
$output->writeln($resultMessage);
59+
return $resultCode;
8560
}
8661
}

Controller/Adminhtml/Config/Job/Run.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Magento\Backend\App\Action\Context;
88
use Magento\Backend\App\Action;
99
use Magento\Framework\Event\ObserverFactory;
10+
use Magento\Framework\Controller\ResultFactory;
1011

1112
class Run extends Action
1213
{
@@ -52,14 +53,15 @@ public function __construct(
5253
*/
5354
public function execute()
5455
{
56+
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
57+
$resultRedirect->setUrl($this->_redirect->getRefererUrl());
5558
try {
5659
$this->cronQueue->execute($this->observer);
5760
} catch (\Magento\Framework\Exception\CronException $e) {
5861
$this->getMessageManager()->addErrorMessage($e->getMessage());
59-
$this->_redirect('*/config/');
60-
return;
62+
return $resultRedirect;
6163
}
6264
$this->getMessageManager()->addSuccessMessage("Magento Cron Ran Successfully");
63-
$this->_redirect('*/config/');
65+
return $resultRedirect;
6466
}
6567
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace EthanYehuda\CronjobManager\Controller\Adminhtml\Manage\Job;
4+
5+
use EthanYehuda\CronjobManager\Api\ScheduleManagementInterface;
6+
use Magento\Backend\App\AbstractAction;
7+
use Magento\Backend\App\Action\Context;
8+
9+
class Kill extends AbstractAction
10+
{
11+
const ADMIN_RESOURCE = "EthanYehuda_CronjobManager::cronjobmanager";
12+
13+
/**
14+
* @var ScheduleManagementInterface
15+
*/
16+
private $scheduleManagement;
17+
18+
/**
19+
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
20+
* @param \Magento\Backend\App\Action\Context $context
21+
*/
22+
public function __construct(
23+
Context $context,
24+
ScheduleManagementInterface $scheduleManagement
25+
) {
26+
parent::__construct($context);
27+
$this->scheduleManagement = $scheduleManagement;
28+
}
29+
30+
/**
31+
* Save cronjob
32+
*
33+
* @return Void
34+
*/
35+
public function execute()
36+
{
37+
$jobId = (int)$this->getRequest()->getParam('id');
38+
$jobCode = $this->getRequest()->getParam('job_code');
39+
try {
40+
if ($this->scheduleManagement->kill($jobId, \time())) {
41+
$this->getMessageManager()->addSuccessMessage("Job will be killed by next cron run: {$jobCode}");
42+
} else {
43+
$this->getMessageManager()->addNoticeMessage("Job cannot be killed.");
44+
}
45+
} catch (\Exception $e) {
46+
$this->getMessageManager()->addErrorMessage($e->getMessage());
47+
$this->_redirect('*/manage/index/');
48+
return;
49+
}
50+
$this->_redirect('*/manage/index/');
51+
}
52+
}

Model/CleanRunningJobs.php

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace EthanYehuda\CronjobManager\Model;
5+
6+
use EthanYehuda\CronjobManager\Api\Data\ScheduleInterface;
7+
use EthanYehuda\CronjobManager\Api\ScheduleRepositoryAdapterInterface;
8+
use Magento\Cron\Model\ResourceModel\Schedule\CollectionFactory;
9+
use Magento\Cron\Model\Schedule;
10+
use Magento\Framework\Stdlib\DateTime\DateTime;
11+
12+
/**
13+
* Update jobs with dead processes from running to error
14+
*/
15+
class CleanRunningJobs
16+
{
17+
/**
18+
* @var ProcessManagement
19+
*/
20+
private $processManagement;
21+
/**
22+
* @var ScheduleRepositoryAdapterInterface
23+
*/
24+
private $scheduleRepository;
25+
/**
26+
* @var Clock
27+
*/
28+
private $clock;
29+
/**
30+
* @var DateTime
31+
*/
32+
private $dateTime;
33+
34+
public function __construct(
35+
ScheduleRepositoryAdapterInterface $scheduleRepository,
36+
ProcessManagement $processManagement,
37+
DateTime $dateTime,
38+
Clock $clock
39+
) {
40+
$this->processManagement = $processManagement;
41+
$this->scheduleRepository = $scheduleRepository;
42+
$this->dateTime = $dateTime;
43+
$this->clock = $clock;
44+
}
45+
46+
/**
47+
* Find all jobs in status "running" (according to db),
48+
* and check if the process is alive. If not, set status to error, with the message
49+
* "Process went away"
50+
*/
51+
public function execute()
52+
{
53+
$runningJobs = $this->scheduleRepository->getByStatus(ScheduleInterface::STATUS_RUNNING);
54+
55+
foreach ($runningJobs as $schedule) {
56+
if ($this->processManagement->isPidAlive($schedule->getPid())) {
57+
continue;
58+
}
59+
60+
$messages = [];
61+
if ($schedule->getMessages()) {
62+
$messages[] = $schedule->getMessages();
63+
}
64+
65+
$messages[] = __('Process went away at %1', $this->dateTime->gmtDate(null, $this->clock->now()));
66+
67+
$schedule
68+
->setStatus(Schedule::STATUS_ERROR)
69+
->setMessages(implode("\n", $messages));
70+
71+
$this->scheduleRepository->save($schedule);
72+
}
73+
}
74+
}

Model/Clock.php

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace EthanYehuda\CronjobManager\Model;
5+
6+
interface Clock
7+
{
8+
public function now(): int;
9+
}

0 commit comments

Comments
 (0)