forked from yiisoft/queue
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Set soft memory limit in the default loop * Add soft limit reached event and signals config * Apply fixes from StyleCI * Make signal list immutable * Add typehints * Remove redundant phpdoc * Divide loops * Apply fixes from StyleCI * Fix signals: SIGSTOP can't be dispatched programmatically * Fix tests
- Loading branch information
1 parent
4bec5ef
commit 93a6642
Showing
6 changed files
with
161 additions
and
56 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,55 +8,39 @@ | |
|
||
namespace Yiisoft\Yii\Queue\Cli; | ||
|
||
/** | ||
* Signal Loop. | ||
* | ||
* @author Roman Zhuravlev <[email protected]> | ||
* | ||
* @since 2.0.2 | ||
*/ | ||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
|
||
class SignalLoop implements LoopInterface | ||
{ | ||
/** | ||
* @var array of signals to exit from listening of the queue. | ||
*/ | ||
protected array $exitSignals = [ | ||
15, // SIGTERM | ||
2, // SIGINT | ||
1, // SIGHUP | ||
]; | ||
/** | ||
* @var array of signals to suspend listening of the queue. | ||
* For example: SIGTSTP | ||
*/ | ||
protected array $suspendSignals = []; | ||
/** | ||
* @var array of signals to resume listening of the queue. | ||
* For example: SIGCONT | ||
*/ | ||
protected array $resumeSignals = []; | ||
use SoftLimitTrait; | ||
|
||
protected const SIGNALS_EXIT = [SIGHUP, SIGINT, SIGTERM]; | ||
protected const SIGNALS_SUSPEND = [SIGTSTP]; | ||
protected const SIGNALS_RESUME = [SIGCONT]; | ||
|
||
protected int $memorySoftLimit; | ||
protected EventDispatcherInterface $dispatcher; | ||
protected bool $pause; | ||
protected bool $exit; | ||
|
||
/** | ||
* @var bool status when exit signal was got. | ||
*/ | ||
protected bool $exit = false; | ||
/** | ||
* @var bool status when suspend or resume signal was got. | ||
* @param EventDispatcherInterface $dispatcher | ||
* @param int $memorySoftLimit Soft RAM limit in bytes. The loop won't let you continue to execute the program if | ||
* soft limit is reached. Zero means no limit. | ||
*/ | ||
protected bool $pause = false; | ||
|
||
public function __construct() | ||
public function __construct(EventDispatcherInterface $dispatcher, int $memorySoftLimit = 0) | ||
{ | ||
if (extension_loaded('pcntl')) { | ||
foreach ($this->exitSignals as $signal) { | ||
pcntl_signal($signal, fn () => $this->exit = true); | ||
} | ||
foreach ($this->suspendSignals as $signal) { | ||
pcntl_signal($signal, fn () => $this->pause = true); | ||
} | ||
foreach ($this->resumeSignals as $signal) { | ||
pcntl_signal($signal, fn () => $this->pause = false); | ||
} | ||
$this->dispatcher = $dispatcher; | ||
$this->memorySoftLimit = $memorySoftLimit; | ||
|
||
foreach (self::SIGNALS_EXIT as $signal) { | ||
pcntl_signal($signal, fn () => $this->exit = true); | ||
} | ||
foreach (self::SIGNALS_SUSPEND as $signal) { | ||
pcntl_signal($signal, fn () => $this->pause = true); | ||
} | ||
foreach (self::SIGNALS_RESUME as $signal) { | ||
pcntl_signal($signal, fn () => $this->pause = false); | ||
} | ||
} | ||
|
||
|
@@ -67,25 +51,36 @@ public function __construct() | |
*/ | ||
public function canContinue(): bool | ||
{ | ||
if (extension_loaded('pcntl')) { | ||
if ($this->memoryLimitReached()) { | ||
return false; | ||
} | ||
|
||
return $this->dispatchSignals(); | ||
} | ||
|
||
protected function dispatchSignals(): bool | ||
{ | ||
$this->pause = false; | ||
$this->exit = false; | ||
|
||
pcntl_signal_dispatch(); | ||
|
||
// Wait for resume signal until loop is suspended | ||
while ($this->pause && !$this->exit) { | ||
usleep(10000); | ||
pcntl_signal_dispatch(); | ||
// Wait for resume signal until loop is suspended | ||
while ($this->pause && !$this->exit) { | ||
usleep(10000); | ||
pcntl_signal_dispatch(); | ||
} | ||
} | ||
|
||
return !$this->exit; | ||
} | ||
|
||
public function setResumeSignals(array $resumeSignals): void | ||
protected function getMemoryLimit(): int | ||
{ | ||
$this->resumeSignals = $resumeSignals; | ||
return $this->memorySoftLimit; | ||
} | ||
|
||
public function setSuspendSignals(array $suspendSignals): void | ||
protected function getEventDispatcher(): EventDispatcherInterface | ||
{ | ||
$this->suspendSignals = $suspendSignals; | ||
return $this->dispatcher; | ||
} | ||
} |
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,47 @@ | ||
<?php | ||
/** | ||
* @link http://www.yiiframework.com/ | ||
* | ||
* @copyright Copyright (c) 2008 Yii Software LLC | ||
* @license http://www.yiiframework.com/license/ | ||
*/ | ||
|
||
namespace Yiisoft\Yii\Queue\Cli; | ||
|
||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
|
||
class SimpleLoop implements LoopInterface | ||
{ | ||
use SoftLimitTrait; | ||
|
||
protected int $memorySoftLimit; | ||
protected EventDispatcherInterface $dispatcher; | ||
|
||
/** | ||
* @param EventDispatcherInterface $dispatcher | ||
* @param int $memorySoftLimit Soft RAM limit in bytes. The loop won't let you continue to execute the program if | ||
* soft limit is reached. Zero means no limit. | ||
*/ | ||
public function __construct( | ||
EventDispatcherInterface $dispatcher, | ||
int $memorySoftLimit = 0 | ||
) { | ||
$this->dispatcher = $dispatcher; | ||
$this->memorySoftLimit = $memorySoftLimit; | ||
} | ||
|
||
public function canContinue(): bool | ||
{ | ||
return !$this->memoryLimitReached(); | ||
} | ||
|
||
protected function getEventDispatcher(): EventDispatcherInterface | ||
{ | ||
return $this->dispatcher; | ||
} | ||
|
||
protected function getMemoryLimit(): int | ||
{ | ||
return $this->memorySoftLimit; | ||
} | ||
} |
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,30 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Queue\Cli; | ||
|
||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
use Yiisoft\Yii\Queue\Event\MemoryLimitReached; | ||
|
||
trait SoftLimitTrait | ||
{ | ||
abstract protected function getMemoryLimit(): int; | ||
abstract protected function getEventDispatcher(): EventDispatcherInterface; | ||
|
||
protected function memoryLimitReached(): bool | ||
{ | ||
$limit = $this->getMemoryLimit(); | ||
|
||
if ($limit !== 0) { | ||
$usage = memory_get_usage(true); | ||
|
||
if ($usage >= $limit) { | ||
$this->getEventDispatcher()->dispatch(new MemoryLimitReached($limit, $usage)); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
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,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Queue\Event; | ||
|
||
class MemoryLimitReached | ||
{ | ||
private int $limit; | ||
private int $actual; | ||
|
||
public function __construct(int $limit, int $actual) | ||
{ | ||
$this->limit = $limit; | ||
$this->actual = $actual; | ||
} | ||
|
||
public function getActualUsage(): int | ||
{ | ||
return $this->actual; | ||
} | ||
|
||
public function getLimit(): int | ||
{ | ||
return $this->limit; | ||
} | ||
} |
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