- Fixes blocking HTTP request issue

- Simplifies cron supervisor
This commit is contained in:
Vlad
2016-07-25 11:54:11 -04:00
parent 3cc5812c1d
commit 3f5c36d2d4
6 changed files with 29 additions and 156 deletions

View File

@ -21,8 +21,6 @@ define(
action: 'getStatus'
})
.done(function(response) {
jQuery('.button-primary')
.removeClass('disabled');
if(response.status !== undefined) {
this.setState(response);
} else {
@ -36,22 +34,6 @@ define(
setInterval(this.getCronData, 5000);
}
},
controlCron: function(action) {
if(jQuery('.button-primary').hasClass('disabled')) {
return;
}
jQuery('.button-primary')
.addClass('disabled');
MailPoet.Ajax.post({
endpoint: 'cron',
action: action,
})
.done(function(response) {
if(!response.result) {
MailPoet.Notice.error(MailPoet.I18n.t('daemonControlError'));
}
}.bind(this));
},
render: function() {
switch(this.state.status) {
case 'loading':
@ -60,48 +42,18 @@ define(
{MailPoet.I18n.t('loadingDaemonStatus')}
</div>
);
case 'started':
return(
<div>
{MailPoet.I18n.t('cronDaemonIsRunning')}
<br/>
<br/>
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'stop')}>{MailPoet.I18n.t('stop')}</a>
</div>
);
break;
case 'starting':
case 'stopping':
return(
<div>
{MailPoet.I18n.t('cronDaemonState').replace('%$1s', this.state.status)}
</div>
);
break;
case 'stopped':
return(
<div>
{MailPoet.I18n.t('cronDaemonState').replace('%$1s', this.state.status)}
<br />
<br />
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'start')}>{MailPoet.I18n.t('start')}</a>
</div>
);
break;
case 'wordpress_task_scheduler_enabled':
return(
<div>
{MailPoet.I18n.t('wordpressTaskSchedulerEnabled')}
</div>
);
break;
case false:
return(
<div>
{MailPoet.I18n.t('daemonNotRunning')}
</div>
);
break;
default:
return(
<div>
{MailPoet.I18n.t('cronDaemonState').replace('%$1s', this.state.status)}
</div>
);
}
}
});

View File

@ -2,31 +2,11 @@
namespace MailPoet\API\Endpoints;
use MailPoet\Cron\CronHelper;
use MailPoet\Cron\CronTrigger;
use MailPoet\Cron\Supervisor;
use MailPoet\Models\Setting;
if(!defined('ABSPATH')) exit;
class Cron {
function start() {
$supervisor = new Supervisor($force_run = true);
return $supervisor->checkDaemon();
}
function stop() {
$daemon = CronHelper::getDaemon();
if(!$daemon || $daemon['status'] !== 'started') {
$result = false;
} else {
$daemon['status'] = 'stopping';
$result = CronHelper::saveDaemon($daemon);
}
return array(
'result' => $result
);
}
function getStatus() {
$daemon = Setting::getValue(CronHelper::DAEMON_SETTING);
return ($daemon) ?

View File

@ -11,10 +11,10 @@ if(!defined('ABSPATH')) exit;
class CronHelper {
const DAEMON_EXECUTION_LIMIT = 20;
const DAEMON_EXECUTION_TIMEOUT = 35;
const DAEMON_REQUEST_TIMEOUT = 2;
const DAEMON_REQUEST_TIMEOUT = 5;
const DAEMON_SETTING = 'cron_daemon';
static function createDaemon($token) {
static function createOrRestartDaemon($token) {
$daemon = array(
'status' => Daemon::STATUS_STARTING,
'token' => $token
@ -49,7 +49,7 @@ class CronHelper {
return Security::generateRandomString();
}
static function accessDaemon($token, $timeout = self::DAEMON_REQUEST_TIMEOUT) {
static function accessDaemon($token) {
$data = array('token' => $token);
$url = FrontRouter::buildRequest(
QueueEndpoint::ENDPOINT,
@ -57,7 +57,9 @@ class CronHelper {
$data
);
$args = array(
'timeout' => $timeout,
'blocking' => false,
'sslverify' => false,
'timeout' => self::DAEMON_REQUEST_TIMEOUT,
'user-agent' => 'MailPoet (www.mailpoet.com) Cron'
);
$result = wp_remote_get($url, $args);

View File

@ -16,7 +16,6 @@ class Daemon {
const STATUS_STOPPING = 'stopping';
const STATUS_STARTED = 'started';
const STATUS_STARTING = 'starting';
const REQUEST_TIMEOUT = 5;
private $timer;
function __construct($data) {
@ -78,13 +77,14 @@ class Daemon {
}
}
function abortWithError($message) {
exit('[mailpoet_cron_error:' . base64_encode($message) . ']');
function callSelf() {
CronHelper::accessDaemon($this->token);
$this->terminateRequest();
}
function callSelf() {
CronHelper::accessDaemon($this->token, self::REQUEST_TIMEOUT);
$this->terminateRequest();
function abortWithError($message) {
status_header(404, $message);
exit;
}
function terminateRequest() {

View File

@ -16,77 +16,19 @@ class Supervisor {
function checkDaemon() {
$daemon = $this->daemon;
if(!$daemon) {
$daemon = CronHelper::createDaemon($this->token);
return $this->runDaemon($daemon);
}
// if the daemon is stopped, return its status and do nothing
if(!$this->force_run &&
isset($daemon['status']) &&
$daemon['status'] === Daemon::STATUS_STOPPED
) {
return $this->formatDaemonStatusMessage($daemon['status']);
}
$elapsed_time = time() - (int)$daemon['updated_at'];
// if it's been less than 40 seconds since last execution and we're not
// force-running the daemon, return its status and do nothing
if($elapsed_time < CronHelper::DAEMON_EXECUTION_TIMEOUT && !$this->force_run) {
return $this->formatDaemonStatusMessage($daemon['status']);
} elseif($elapsed_time < CronHelper::DAEMON_EXECUTION_TIMEOUT &&
$this->force_run &&
in_array($daemon['status'], array(
Daemon::STATUS_STOPPING,
Daemon::STATUS_STARTING
))
) {
// if it's been less than 40 seconds since last execution, we are
// force-running the daemon and it's either being started or stopped,
// return its status and do nothing
return $this->formatDaemonStatusMessage($daemon['status']);
}
// re-create (restart) daemon
CronHelper::createDaemon($this->token);
$execution_timeout_exceeded = ($daemon) ?
(time() - (int)$daemon['updated_at']) > CronHelper::DAEMON_EXECUTION_TIMEOUT :
false;
if(!$daemon || $execution_timeout_exceeded) {
CronHelper::createOrRestartDaemon($this->token);
return $this->runDaemon();
}
return $daemon;
}
function runDaemon() {
$request = CronHelper::accessDaemon($this->token);
preg_match('/\[(mailpoet_cron_error:.*?)\]/i', $request, $status);
CronHelper::accessDaemon($this->token);
$daemon = CronHelper::getDaemon();
if(!empty($status) || !$daemon) {
if(!$daemon) {
$message = __('Daemon failed to run.');
} else {
list(, $message) = explode(':', $status[0]);
$message = base64_decode($message);
}
return $this->formatResultMessage(
false,
$message
);
}
return $this->formatDaemonStatusMessage($daemon['status']);
}
private function formatDaemonStatusMessage($status) {
return $this->formatResultMessage(
true,
sprintf(
__('Daemon is currently %s.'),
__($status)
)
);
}
private function formatResultMessage($result, $message) {
$formattedResult = array(
'result' => $result
);
if(!$result) {
$formattedResult['errors'] = array($message);
} else {
$formattedResult['message'] = $message;
}
return $formattedResult;
return $daemon;
}
}

View File

@ -7,12 +7,9 @@
<% block translations %>
<%= localize({
'daemonNotRunning': __('Daemon is not running'),
'wordpressTaskSchedulerEnabled': __('Daemon is not running because WordPress task scheduler is enabled and there are no scheduled or in-progress jobs'),
'daemonControlError': __('Cron daemon error'),
'loadingDaemonStatus': __('Loading daemon status...'),
'cronDaemonIsRunning': __('Cron daemon is running'),
'stop': __('Stop'),
'start': __('Start'),
'cronDaemonState': __('Cron is %$1s')
}) %>
<% endblock %>