mirror of
https://github.com/danog/loop.git
synced 2024-11-30 04:19:04 +01:00
Fix memory leak
This commit is contained in:
parent
8309d5be1d
commit
59354bb12d
@ -52,7 +52,6 @@ class MyLoop extends Loop
|
|||||||
*/
|
*/
|
||||||
protected function startedLoop(): void
|
protected function startedLoop(): void
|
||||||
{
|
{
|
||||||
parent::startedLoop();
|
|
||||||
echo "Started loop $this!".PHP_EOL;
|
echo "Started loop $this!".PHP_EOL;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -61,7 +60,6 @@ class MyLoop extends Loop
|
|||||||
*/
|
*/
|
||||||
protected function exitedLoop(): void
|
protected function exitedLoop(): void
|
||||||
{
|
{
|
||||||
parent::exitedLoop();
|
|
||||||
echo "Exited loop $this!".PHP_EOL;
|
echo "Exited loop $this!".PHP_EOL;
|
||||||
}
|
}
|
||||||
// End of logging methods
|
// End of logging methods
|
||||||
|
@ -43,7 +43,6 @@ class MyLoop extends ResumableLoop
|
|||||||
*/
|
*/
|
||||||
protected function startedLoop(): void
|
protected function startedLoop(): void
|
||||||
{
|
{
|
||||||
parent::startedLoop();
|
|
||||||
echo "Started loop $this!".PHP_EOL;
|
echo "Started loop $this!".PHP_EOL;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -52,7 +51,6 @@ class MyLoop extends ResumableLoop
|
|||||||
*/
|
*/
|
||||||
protected function exitedLoop(): void
|
protected function exitedLoop(): void
|
||||||
{
|
{
|
||||||
parent::exitedLoop();
|
|
||||||
echo "Exited loop $this!".PHP_EOL;
|
echo "Exited loop $this!".PHP_EOL;
|
||||||
}
|
}
|
||||||
// End of logging methods
|
// End of logging methods
|
||||||
|
@ -18,18 +18,6 @@ use function Amp\async;
|
|||||||
/**
|
/**
|
||||||
* Generic loop, runs single callable.
|
* Generic loop, runs single callable.
|
||||||
*
|
*
|
||||||
* The return value of the callable can be:
|
|
||||||
* * A number - the loop will be paused for the specified number of seconds
|
|
||||||
* * GenericLoop::STOP - The loop will stop
|
|
||||||
* * GenericLoop::PAUSE - The loop will pause forever (or until loop is `resumed()`
|
|
||||||
* from outside the loop)
|
|
||||||
* * GenericLoop::CONTINUE - Return this if you want to rerun the loop immediately
|
|
||||||
*
|
|
||||||
* If the callable does not return anything,
|
|
||||||
* the loop will behave is if GenericLoop::PAUSE was returned.
|
|
||||||
*
|
|
||||||
* The loop can be stopped from the outside by signaling `true`.
|
|
||||||
*
|
|
||||||
* @psalm-type TCallableReturn=int|null|Future<int|null>
|
* @psalm-type TCallableReturn=int|null|Future<int|null>
|
||||||
*
|
*
|
||||||
* @author Daniil Gentili <daniil@daniil.it>
|
* @author Daniil Gentili <daniil@daniil.it>
|
||||||
@ -57,6 +45,18 @@ class GenericLoop extends ResumableSignalLoop
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* The return value of the callable can be:
|
||||||
|
* * A number - the loop will be paused for the specified number of seconds
|
||||||
|
* * GenericLoop::STOP - The loop will stop
|
||||||
|
* * GenericLoop::PAUSE - The loop will pause forever (or until loop is `resumed()`
|
||||||
|
* from outside the loop)
|
||||||
|
* * GenericLoop::CONTINUE - Return this if you want to rerun the loop immediately
|
||||||
|
*
|
||||||
|
* If the callable does not return anything,
|
||||||
|
* the loop will behave is if GenericLoop::PAUSE was returned.
|
||||||
|
*
|
||||||
|
* The loop can be stopped from the outside by signaling `true`.
|
||||||
|
*
|
||||||
* If possible, the callable will be bound to the current instance of the loop.
|
* If possible, the callable will be bound to the current instance of the loop.
|
||||||
*
|
*
|
||||||
* @param callable():TCallableReturn $callable Callable to run
|
* @param callable():TCallableReturn $callable Callable to run
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
namespace danog\Loop\Traits;
|
namespace danog\Loop\Traits;
|
||||||
|
|
||||||
use function Amp\async;
|
use danog\Loop\Interfaces\LoopInterface;
|
||||||
|
use Revolt\EventLoop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop helper trait.
|
* Loop helper trait.
|
||||||
@ -17,43 +18,51 @@ use function Amp\async;
|
|||||||
* Wraps the asynchronous generator methods with asynchronous promise-based methods
|
* Wraps the asynchronous generator methods with asynchronous promise-based methods
|
||||||
*
|
*
|
||||||
* @author Daniil Gentili <daniil@daniil.it>
|
* @author Daniil Gentili <daniil@daniil.it>
|
||||||
|
*
|
||||||
|
* @psalm-require-implements LoopInterface
|
||||||
*/
|
*/
|
||||||
trait Loop
|
trait Loop
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Whether the loop was started.
|
* Whether the loop was started.
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
*/
|
||||||
private $started = false;
|
private bool $started = false;
|
||||||
/**
|
/**
|
||||||
* Start the loop.
|
* Start the loop.
|
||||||
*
|
*
|
||||||
* Returns false if the loop is already running.
|
* Returns false if the loop is already running.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function start(): bool
|
public function start(): bool
|
||||||
{
|
{
|
||||||
if ($this->started) {
|
if ($this->started) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
async(function (): void {
|
EventLoop::queue(function (): void {
|
||||||
$this->startedLoop();
|
$this->startedLoopInternal();
|
||||||
try {
|
try {
|
||||||
$this->loop();
|
$this->loop();
|
||||||
} finally {
|
} finally {
|
||||||
$this->exitedLoop();
|
$this->exitedLoopInternal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
private function exitedLoopInternal(): void
|
||||||
|
{
|
||||||
|
$this->started = false;
|
||||||
|
$this->exitedLoop();
|
||||||
|
}
|
||||||
|
private function startedLoopInternal(): void
|
||||||
|
{
|
||||||
|
$this->started = true;
|
||||||
|
$this->startedLoop();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Signal that loop has exIited.
|
* Signal that loop has exited.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function exitedLoop(): void
|
protected function exitedLoop(): void
|
||||||
{
|
{
|
||||||
$this->started = false;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Signal that loop has started.
|
* Signal that loop has started.
|
||||||
@ -61,7 +70,6 @@ trait Loop
|
|||||||
*/
|
*/
|
||||||
protected function startedLoop(): void
|
protected function startedLoop(): void
|
||||||
{
|
{
|
||||||
$this->started = true;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Check whether loop is running.
|
* Check whether loop is running.
|
||||||
|
@ -22,7 +22,7 @@ use Revolt\EventLoop;
|
|||||||
trait ResumableLoop
|
trait ResumableLoop
|
||||||
{
|
{
|
||||||
use Loop {
|
use Loop {
|
||||||
exitedLoop as private parentExitedLoop;
|
exitedLoopInternal as private parentExitedLoop;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Resume deferred.
|
* Resume deferred.
|
||||||
@ -66,7 +66,7 @@ trait ResumableLoop
|
|||||||
/** @var DeferredFuture<null> */
|
/** @var DeferredFuture<null> */
|
||||||
$this->pause = new DeferredFuture();
|
$this->pause = new DeferredFuture();
|
||||||
if ($pause) {
|
if ($pause) {
|
||||||
EventLoop::defer(function () use ($pause): void { $pause->complete(); });
|
EventLoop::queue($pause->complete(...));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var DeferredFuture<null> */
|
/** @var DeferredFuture<null> */
|
||||||
@ -95,7 +95,7 @@ trait ResumableLoop
|
|||||||
*/
|
*/
|
||||||
public function resumeDefer(): Future
|
public function resumeDefer(): Future
|
||||||
{
|
{
|
||||||
EventLoop::defer($this->resumeInternal(...));
|
EventLoop::queue($this->resumeInternal(...));
|
||||||
if (!$this->pause) {
|
if (!$this->pause) {
|
||||||
/** @var DeferredFuture<null> */
|
/** @var DeferredFuture<null> */
|
||||||
$this->pause = new DeferredFuture;
|
$this->pause = new DeferredFuture;
|
||||||
@ -143,12 +143,9 @@ trait ResumableLoop
|
|||||||
/**
|
/**
|
||||||
* Signal that loop has exited.
|
* Signal that loop has exited.
|
||||||
*/
|
*/
|
||||||
protected function exitedLoop(): void
|
private function exitedLoopInternal(): void
|
||||||
{
|
{
|
||||||
|
$this->resumeInternal();
|
||||||
$this->parentExitedLoop();
|
$this->parentExitedLoop();
|
||||||
if ($this->resumeTimer) {
|
|
||||||
EventLoop::cancel($this->resumeTimer);
|
|
||||||
$this->resumeTimer = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="https://getpsalm.org/schema/config"
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||||
|
errorBaseline="psalm-baseline.xml"
|
||||||
>
|
>
|
||||||
<projectFiles>
|
<projectFiles>
|
||||||
<directory name="lib" />
|
<directory name="lib" />
|
||||||
|
@ -13,34 +13,28 @@ trait Logging
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Check whether the loop started.
|
* Check whether the loop started.
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $startCounter = 0;
|
private int $startCounter = 0;
|
||||||
/**
|
/**
|
||||||
* Check whether the loop ended.
|
* Check whether the loop ended.
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $endCounter = 0;
|
private int $endCounter = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal that loop started.
|
* Signal that loop started.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function startedLoop(): void
|
final protected function startedLoop(): void
|
||||||
{
|
{
|
||||||
$this->startCounter++;
|
$this->startCounter++;
|
||||||
parent::startedLoop();
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Signal that loop ended.
|
* Signal that loop ended.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function exitedLoop(): void
|
final protected function exitedLoop(): void
|
||||||
{
|
{
|
||||||
$this->endCounter++;
|
$this->endCounter++;
|
||||||
parent::exitedLoop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user