Skip to content

Commit

Permalink
Register with the loop
Browse files Browse the repository at this point in the history
  • Loading branch information
mbabker committed May 31, 2024
1 parent dfa6e76 commit e2c6a19
Show file tree
Hide file tree
Showing 7 changed files with 9 additions and 65 deletions.
23 changes: 2 additions & 21 deletions docs/periodic-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ Periodic managers are initialized during the `BabDev\WebSocketBundle\Event\Befor

A manager must provide a unique name, these names are used in conjunction with the `BabDev\WebSocketBundle\PeriodicManager\PeriodicManagerRegistry`

### `setLoop()`

When managers are registered, they will be provided the event loop that is being used for the server process.

### `register()`

The `register()` method is used to initialize the periodic manager.
The `register()` method is used to initialize the periodic manager using the provided event loop.

### `cancelTimers()`

Expand All @@ -29,7 +25,6 @@ The `cancelTimers()` method is called during the `BabDev\WebSocketBundle\Event\A

namespace App\WebSocket\PeriodicManager;

use BabDev\WebSocketBundle\Exception\MissingLoop;
use BabDev\WebSocketBundle\PeriodicManager\PeriodicManager;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
Expand All @@ -46,33 +41,19 @@ final class EchoPeriodicManager implements PeriodicManager, LoggerAwareInterface
return 'echo'
}

public function setLoop(LoopInterface $loop): void
public function register(LoopInterface $loop): void
{
$this->loop = $loop;
}

public function register(): void
{
// Wrap the entire loop in try/catch to prevent fatal errors crashing the websocket server
try {
if (null === $this->loop) {
throw new MissingLoop(sprintf('The event loop has not been registered in %s', self::class));
}

// Register the timer to run every 15 seconds
$this->loop->addPeriodicTimer(
15,
static function (): void {
echo 'This is a demo';
},
);
} catch (MissingLoopException $exception) {
$this->logger->error(
$exception->getMessage(),
[
'exception' => $exception,
],
);
} catch (\Throwable $exception) {
$this->logger->error(
'Uncaught Throwable in the echo manager.',
Expand Down
5 changes: 1 addition & 4 deletions src/EventListener/PeriodicManagerSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@ public function onAfterServerClosed(AfterServerClosed $event): void

public function onBeforeRunServer(BeforeRunServer $event): void
{
$loop = $event->loop;

foreach ($this->registry->getManagers() as $manager) {
$manager->setLoop($loop);
$manager->register();
$manager->register($event->loop);
}
}
}
7 changes: 0 additions & 7 deletions src/Exception/MissingLoop.php

This file was deleted.

8 changes: 1 addition & 7 deletions src/PeriodicManager/PeriodicManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@

namespace BabDev\WebSocketBundle\PeriodicManager;

use BabDev\WebSocketBundle\Exception\MissingLoop;
use React\EventLoop\LoopInterface;

interface PeriodicManager
{
public function getName(): string;

/**
* @throws MissingLoop if called before setting the event loop
*/
public function register(): void;
public function register(LoopInterface $loop): void;

public function cancelTimers(): void;

public function setLoop(LoopInterface $loop): void;
}
16 changes: 3 additions & 13 deletions src/PeriodicManager/PingDoctrineDBALConnectionsPeriodicManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace BabDev\WebSocketBundle\PeriodicManager;

use BabDev\WebSocketBundle\Exception\MissingLoop;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception as DBALException;
use Psr\Log\LoggerAwareInterface;
Expand Down Expand Up @@ -30,22 +29,18 @@ public function getName(): string
return 'ping_doctrine_dbal_connections';
}

public function register(): void
public function register(LoopInterface $loop): void
{
$this->loop = $loop;

// Wrap the entire loop in try/catch to prevent fatal errors crashing the websocket server
try {
$this->logger?->info('Registering ping doctrine/dbal connections manager.');

if (!$this->loop instanceof LoopInterface) {
throw new MissingLoop(sprintf('The event loop has not been registered in %s', self::class));
}

$this->timer = $this->loop->addPeriodicTimer(
$this->interval,
$this->pingConnections(...),
);
} catch (MissingLoop $exception) {
$this->logger?->error($exception->getMessage(), ['exception' => $exception]);
} catch (\Throwable $exception) {
$this->logger?->error('Uncaught Throwable in the ping doctrine/dbal connections loop.', ['exception' => $exception]);
}
Expand All @@ -56,11 +51,6 @@ public function cancelTimers(): void
$this->reset();
}

public function setLoop(LoopInterface $loop): void
{
$this->loop = $loop;
}

/**
* @internal
*/
Expand Down
5 changes: 1 addition & 4 deletions tests/EventListener/PeriodicManagerSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,9 @@ public function testInitializesPeriodicManagers(): void
/** @var MockObject&PeriodicManager $manager */
$manager = $this->createMock(PeriodicManager::class);
$manager->expects(self::once())
->method('setLoop')
->method('register')
->with($loop);

$manager->expects(self::once())
->method('register');

$this->registry->method('getManagers')
->willReturn(['test' => $manager]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ protected function tearDown(): void
parent::tearDown();
}

public function testTheManagerIsNotRegisteredWhenTheLoopIsMissing(): void
{
$this->manager->register();

self::assertTrue($this->logger->hasErrorThatContains(sprintf('The event loop has not been registered in %s', PingDoctrineDBALConnectionsPeriodicManager::class)));
}

public function testTheManagerIsRegistered(): void
{
/** @var MockObject&LoopInterface $loop */
Expand All @@ -59,8 +52,7 @@ public function testTheManagerIsRegistered(): void
->method('addPeriodicTimer')
->willReturn($this->createMock(TimerInterface::class));

$this->manager->setLoop($loop);
$this->manager->register();
$this->manager->register($loop);
}

public function testTheManagerPingsAllConnections(): void
Expand Down

0 comments on commit e2c6a19

Please sign in to comment.