laravel的计划任务确实好用,之前就计划吧这个功能研究下,自己造一个给tp5使用
但是研究之后发现,容器这个概念吧代码变得比较抽象,代码读起来的难度比较高
然后研究之后发现除了phpstorm可以追踪大部分代码之外,其他的ide代码追踪功能真的很一般,比如我一般使用NetBeans
看官网在开发9.0不知道啥时候了,等等吧
2018年7月30日11:01:42
补充:laravel主要使用的是容器来实现功能的注册,绑定,使用的 ,但是我逐渐发现laravel的慢的原因估计也是因为这个,虽然容器实现了对象池,但是大多数的调用还是new,理论上都是在对象池只有一个,但是new的东西太多
使用起来更容易了,但是代码可读性也越差了,很多IDE都没办法追踪源代码了
现在对于容器的好与坏,确实有待商榷,现在tp也开始学习这套东西,不知是好是坏
laravel的实现原理就是利用 crontab 每分钟执行一次
计算任务的所需要执行的时间,加上互斥保证只执行一次,防止其他用户执行, 判断是否已经执行过
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
这个就是官方提供的执行计划任务的crontab脚本
提供部分代码参考
public function command($command, array $parameters = [])
{
if (class_exists($command)) {
$command = Container::getInstance()->make($command)->getName();
}
return $this->exec(
Application::formatCommandString($command), $parameters
);
}
执行普通命令 php artisan xxxTask
php artisan schedule:run
class CronExpression
{
const MINUTE = 0;
const HOUR = 1;
const DAY = 2;
const MONTH = 3;
const WEEKDAY = 4;
const YEAR = 5;
/**
* @var array CRON expression parts
*/
private $cronParts;
/**
* @var FieldFactory CRON field factory
*/
private $fieldFactory;
/**
* @var int Max iteration count when searching for next run date
*/
private $maxIterationCount = 1000;
/**
* @var array Order in which to test of cron parts
*/
private static $order = array(self::YEAR, self::MONTH, self::DAY, self::WEEKDAY, self::HOUR, self::MINUTE);
/**
* Factory method to create a new CronExpression.
*
* @param string $expression The CRON expression to create. There are
* several special predefined values which can be used to substitute the
* CRON expression:
*
* `@yearly`, `@annually` - Run once a year, midnight, Jan. 1 - 0 0 1 1 *
* `@monthly` - Run once a month, midnight, first of month - 0 0 1 * *
* `@weekly` - Run once a week, midnight on Sun - 0 0 * * 0
* `@daily` - Run once a day, midnight - 0 0 * * *
* `@hourly` - Run once an hour, first minute - 0 * * * *
* @param FieldFactory $fieldFactory Field factory to use
*
* @return CronExpression
*/
public static function factory($expression, FieldFactory $fieldFactory = null)
{
$mappings = array(
'@yearly' => '0 0 1 1 *',
'@annually' => '0 0 1 1 *',
'@monthly' => '0 0 1 * *',
'@weekly' => '0 0 * * 0',
'@daily' => '0 0 * * *',
'@hourly' => '0 * * * *'
);
if (isset($mappings[$expression])) {
$expression = $mappings[$expression];
}
return new static($expression, $fieldFactory ?: new FieldFactory());
}
/**
* Get the next or previous run date of the expression relative to a date
*
* @param string|\DateTime $currentTime Relative calculation date
* @param int $nth Number of matches to skip before returning
* @param bool $invert Set to TRUE to go backwards in time
* @param bool $allowCurrentDate Set to TRUE to return the
* current date if it matches the cron expression
*
* @return \DateTime
* @throws \RuntimeException on too many iterations
*/
protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false)
{
if ($currentTime instanceof DateTime) {
$currentDate = clone $currentTime;
} elseif ($currentTime instanceof DateTimeImmutable) {
$currentDate = DateTime::createFromFormat('U', $currentTime->format('U'));
$currentDate->setTimezone($currentTime->getTimezone());
} else {
$currentDate = new DateTime($currentTime ?: 'now');
$currentDate->setTimezone(new DateTimeZone(date_default_timezone_get()));
}
$currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0);
$nextRun = clone $currentDate;
$nth = (int) $nth;
// We don't have to satisfy * or null fields
$parts = array();
$fields = array();
foreach (self::$order as $position) {
$part = $this->getExpression($position);
if (null === $part || '*' === $part) {
continue;
}
$parts[$position] = $part;
$fields[$position] = $this->fieldFactory->getField($position);
}
// Set a hard limit to bail on an impossible date
for ($i = 0; $i < $this->maxIterationCount; $i++) {
foreach ($parts as $position => $part) {
$satisfied = false;
// Get the field object used to validate this part
$field = $fields[$position];
// Check if this is singular or a list
if (strpos($part, ',') === false) {
$satisfied = $field->isSatisfiedBy($nextRun, $part);
} else {
foreach (array_map('trim', explode(',', $part)) as $listPart) {
if ($field->isSatisfiedBy($nextRun, $listPart)) {
$satisfied = true;
break;
}
}
}
// If the field is not satisfied, then start over
if (!$satisfied) {
$field->increment($nextRun, $invert, $part);
continue 2;
}
}
// Skip this match if needed
if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) {
$this->fieldFactory->getField(0)->increment($nextRun, $invert, isset($parts[0]) ? $parts[0] : null);
continue;
}
return $nextRun;
}
// @codeCoverageIgnoreStart
throw new RuntimeException('Impossible CRON expression');
// @codeCoverageIgnoreEnd
}
判断需要执行的任务是否是当前任务
namespace Illuminate\Console\Scheduling;
use Illuminate\Contracts\Cache\Repository as Cache;
class CacheMutex implements Mutex
{
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
public $cache;
/**
* Create a new overlapping strategy.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
/**
* Attempt to obtain a mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
*/
public function create(Event $event)
{
return $this->cache->add(
$event->mutexName(), true, $event->expiresAt
);
}
/**
* Determine if a mutex exists for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
*/
public function exists(Event $event)
{
return $this->cache->has($event->mutexName());
}
/**
* Clear the mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return void
*/
public function forget(Event $event)
{
$this->cache->forget($event->mutexName());
}
}
互斥 的实现
protected function expressionPasses()
{
$date = Carbon::now();
if ($this->timezone) {
$date->setTimezone($this->timezone);
}
return CronExpression::factory($this->expression)->isDue($date->toDateTimeString());
}
是否过期
自己实现一个计划任务
https://www.cnblogs.com/zx-admin/p/15641124.html