-
-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #100 from magento-hackathon/process-management
Process management
- Loading branch information
Showing
32 changed files
with
954 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
namespace EthanYehuda\CronjobManager\Controller\Adminhtml\Manage\Job; | ||
|
||
use EthanYehuda\CronjobManager\Api\ScheduleManagementInterface; | ||
use Magento\Backend\App\AbstractAction; | ||
use Magento\Backend\App\Action\Context; | ||
|
||
class Kill extends AbstractAction | ||
{ | ||
const ADMIN_RESOURCE = "EthanYehuda_CronjobManager::cronjobmanager"; | ||
|
||
/** | ||
* @var ScheduleManagementInterface | ||
*/ | ||
private $scheduleManagement; | ||
|
||
/** | ||
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory | ||
* @param \Magento\Backend\App\Action\Context $context | ||
*/ | ||
public function __construct( | ||
Context $context, | ||
ScheduleManagementInterface $scheduleManagement | ||
) { | ||
parent::__construct($context); | ||
$this->scheduleManagement = $scheduleManagement; | ||
} | ||
|
||
/** | ||
* Save cronjob | ||
* | ||
* @return Void | ||
*/ | ||
public function execute() | ||
{ | ||
$jobId = (int)$this->getRequest()->getParam('id'); | ||
$jobCode = $this->getRequest()->getParam('job_code'); | ||
try { | ||
if ($this->scheduleManagement->kill($jobId, \time())) { | ||
$this->getMessageManager()->addSuccessMessage("Job will be killed by next cron run: {$jobCode}"); | ||
} else { | ||
$this->getMessageManager()->addNoticeMessage("Job cannot be killed."); | ||
} | ||
} catch (\Exception $e) { | ||
$this->getMessageManager()->addErrorMessage($e->getMessage()); | ||
$this->_redirect('*/manage/index/'); | ||
return; | ||
} | ||
$this->_redirect('*/manage/index/'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace EthanYehuda\CronjobManager\Model; | ||
|
||
use EthanYehuda\CronjobManager\Api\Data\ScheduleInterface; | ||
use EthanYehuda\CronjobManager\Api\ScheduleRepositoryAdapterInterface; | ||
use Magento\Cron\Model\ResourceModel\Schedule\CollectionFactory; | ||
use Magento\Cron\Model\Schedule; | ||
use Magento\Framework\Stdlib\DateTime\DateTime; | ||
|
||
/** | ||
* Update jobs with dead processes from running to error | ||
*/ | ||
class CleanRunningJobs | ||
{ | ||
/** | ||
* @var ProcessManagement | ||
*/ | ||
private $processManagement; | ||
/** | ||
* @var ScheduleRepositoryAdapterInterface | ||
*/ | ||
private $scheduleRepository; | ||
/** | ||
* @var Clock | ||
*/ | ||
private $clock; | ||
/** | ||
* @var DateTime | ||
*/ | ||
private $dateTime; | ||
|
||
public function __construct( | ||
ScheduleRepositoryAdapterInterface $scheduleRepository, | ||
ProcessManagement $processManagement, | ||
DateTime $dateTime, | ||
Clock $clock | ||
) { | ||
$this->processManagement = $processManagement; | ||
$this->scheduleRepository = $scheduleRepository; | ||
$this->dateTime = $dateTime; | ||
$this->clock = $clock; | ||
} | ||
|
||
/** | ||
* Find all jobs in status "running" (according to db), | ||
* and check if the process is alive. If not, set status to error, with the message | ||
* "Process went away" | ||
*/ | ||
public function execute() | ||
{ | ||
$runningJobs = $this->scheduleRepository->getByStatus(ScheduleInterface::STATUS_RUNNING); | ||
|
||
foreach ($runningJobs as $schedule) { | ||
if ($this->processManagement->isPidAlive($schedule->getPid())) { | ||
continue; | ||
} | ||
|
||
$messages = []; | ||
if ($schedule->getMessages()) { | ||
$messages[] = $schedule->getMessages(); | ||
} | ||
|
||
$messages[] = __('Process went away at %1', $this->dateTime->gmtDate(null, $this->clock->now())); | ||
|
||
$schedule | ||
->setStatus(Schedule::STATUS_ERROR) | ||
->setMessages(implode("\n", $messages)); | ||
|
||
$this->scheduleRepository->save($schedule); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace EthanYehuda\CronjobManager\Model; | ||
|
||
interface Clock | ||
{ | ||
public function now(): int; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace EthanYehuda\CronjobManager\Model; | ||
|
||
use EthanYehuda\CronjobManager\Api\Data\ScheduleInterface; | ||
use EthanYehuda\CronjobManager\Api\ScheduleRepositoryAdapterInterface; | ||
use Magento\Framework\Stdlib\DateTime\DateTime; | ||
|
||
class ProcessKillRequests | ||
{ | ||
/** | ||
* @var ProcessManagement | ||
*/ | ||
private $processManagement; | ||
|
||
/** | ||
* @var ScheduleRepositoryAdapterInterface | ||
*/ | ||
private $scheduleRepository; | ||
/** | ||
* @var DateTime | ||
*/ | ||
private $dateTime; | ||
/** | ||
* @var Clock | ||
*/ | ||
private $clock; | ||
|
||
public function __construct( | ||
ScheduleRepositoryAdapterInterface $scheduleRepository, | ||
ProcessManagement $processManagement, | ||
DateTime $dateTime, | ||
Clock $clock | ||
) { | ||
$this->processManagement = $processManagement; | ||
$this->scheduleRepository = $scheduleRepository; | ||
$this->dateTime = $dateTime; | ||
$this->clock = $clock; | ||
} | ||
|
||
public function execute() | ||
{ | ||
$runningJobs = $this->scheduleRepository->getByStatus(ScheduleInterface::STATUS_RUNNING); | ||
foreach ($runningJobs as $schedule) { | ||
if ($schedule->getKillRequest() && $schedule->getKillRequest() <= \time() && $schedule->getPid()) { | ||
$this->killScheduleProcess($schedule); | ||
} | ||
} | ||
} | ||
|
||
private function killScheduleProcess(ScheduleInterface $schedule): void | ||
{ | ||
if ($this->processManagement->killPid($schedule->getPid())) { | ||
$messages = []; | ||
if ($schedule->getMessages()) { | ||
$messages[] = $schedule->getMessages(); | ||
} | ||
$messages[] = 'Process was killed at ' . $this->dateTime->gmtDate(null, $this->clock->now()); | ||
$schedule | ||
->setMessages(\implode("\n", $messages)) | ||
->setStatus(ScheduleInterface::STATUS_KILLED); | ||
|
||
$this->scheduleRepository->save($schedule); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace EthanYehuda\CronjobManager\Model; | ||
|
||
class ProcessManagement | ||
{ | ||
const SIGKILL = 9; | ||
|
||
public function isPidAlive(int $pid): bool | ||
{ | ||
return \file_exists('/proc/' . $pid); | ||
} | ||
|
||
public function killPid($pid): bool | ||
{ | ||
if (!$this->isPidAlive($pid)) { | ||
return false; | ||
} | ||
//TODO first try to send SIGINT, wait up to X seconds, then send SIGKILL if process still running | ||
$killed = \posix_kill($pid, self::SIGKILL); | ||
if ($killed && !$this->isPidAlive($pid)) { | ||
\sleep(5); | ||
if ($this->isPidAlive($pid)) { | ||
return false; | ||
} | ||
} | ||
return $killed; | ||
|
||
} | ||
} |
Oops, something went wrong.