Fixed bug that crontab cannot be closed safely in coroutine server. (#3960)

This commit is contained in:
李铭昕 2021-08-19 10:21:00 +08:00 committed by GitHub
parent 3e0b43a42d
commit 63c82e4d5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 4 deletions

View File

@ -3,6 +3,7 @@
## Fixed
- [#3959](https://github.com/hyperf/hyperf/pull/3959) Fixed validate rule `date` does not work as expected when the value isn't string.
- [#3960](https://github.com/hyperf/hyperf/pull/3960) Fixed bug that crontab cannot be closed safely in coroutine style server.
## Optimized

View File

@ -18,6 +18,8 @@ use Hyperf\Crontab\Scheduler;
use Hyperf\Crontab\Strategy\StrategyInterface;
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\ProcessManager;
use Hyperf\Utils\Coordinator\Constants;
use Hyperf\Utils\Coordinator\CoordinatorManager;
use Psr\Container\ContainerInterface;
use Swoole\Server;
@ -77,7 +79,9 @@ class CrontabDispatcherProcess extends AbstractProcess
{
$this->event->dispatch(new CrontabDispatcherStarted());
while (ProcessManager::isRunning()) {
$this->sleep();
if ($this->sleep()) {
break;
}
$crontabs = $this->scheduler->schedule();
while (! $crontabs->isEmpty()) {
$crontab = $crontabs->dequeue();
@ -86,11 +90,20 @@ class CrontabDispatcherProcess extends AbstractProcess
}
}
private function sleep()
/**
* @return bool whether the server shutdown
*/
private function sleep(): bool
{
$current = date('s', time());
$sleep = 60 - $current;
$this->logger->debug('Crontab dispatcher sleep ' . $sleep . 's.');
$sleep > 0 && \Swoole\Coroutine::sleep($sleep);
if ($sleep > 0) {
if (CoordinatorManager::until(Constants::WORKER_EXIT)->yield($sleep)) {
return true;
}
}
return false;
}
}

View File

@ -13,6 +13,8 @@ namespace Hyperf\Crontab\Strategy;
use Carbon\Carbon;
use Hyperf\Crontab\Crontab;
use Hyperf\Utils\Coordinator\Constants;
use Hyperf\Utils\Coordinator\CoordinatorManager;
use Hyperf\Utils\Coroutine;
class CoroutineStrategy extends AbstractStrategy
@ -22,7 +24,11 @@ class CoroutineStrategy extends AbstractStrategy
Coroutine::create(function () use ($crontab) {
if ($crontab->getExecuteTime() instanceof Carbon) {
$wait = $crontab->getExecuteTime()->getTimeStamp() - time();
$wait > 0 && \Swoole\Coroutine::sleep($wait);
if ($wait > 0) {
if (CoordinatorManager::until(Constants::WORKER_EXIT)->yield($wait)) {
return;
}
}
$executor = $this->container->get(Executor::class);
$executor->execute($crontab);
}