- Installed
iputils-ping
APT-package (for Debian) - PHP >= 8.0
- Installed
doctrine/dbal
,symfony/process
anddoctrine/doctrine-bundle
Composer packages
Created
November 29, 2024 21:45
-
-
Save 7-zete-7/81f7b83e384b15726fcf25d1515aced1 to your computer and use it in GitHub Desktop.
Doctrine DBAL Ping Connection Middleware
This file contains hidden or 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
<?php | |
declare(strict_types=1); | |
namespace App\Doctrine\DBAL\Middleware\PingConnection; | |
use Doctrine\DBAL\ConnectionException; | |
use Doctrine\DBAL\Driver as DriverInterface; | |
use Doctrine\DBAL\Driver\Connection; | |
use Doctrine\DBAL\Driver\Exception as DriverException; | |
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware; | |
use SensitiveParameter; | |
use Symfony\Component\Process\Process; | |
final class Driver extends AbstractDriverMiddleware | |
{ | |
public function __construct( | |
DriverInterface $wrappedDriver, | |
private readonly int $timeout, | |
) { | |
parent::__construct($wrappedDriver); | |
} | |
/** | |
* @throws ConnectionException | |
* @throws DriverException | |
*/ | |
public function connect(#[SensitiveParameter] array $params): Connection | |
{ | |
if (!$this->pingConnection($params['host'])) { | |
throw new ConnectionException(\sprintf('Host "%s" is unreachable.', $params['host'])); | |
} | |
return parent::connect($params); | |
} | |
private function pingConnection(string $host): bool | |
{ | |
$process = new Process([ | |
'ping', // man ping (8) | |
// Stop after sending count ECHO_REQUEST packets. | |
// With deadline option, ping waits for count ECHO_REPLY packets, | |
// until the timeout expires. | |
'-c1', | |
// Quiet output. Nothing is displayed except the summary lines | |
// at startup time and when finished. | |
'-q', | |
// Specify a timeout, in seconds, before ping exits regardless | |
// of how many packets have been sent or received. | |
// In this case ping does not stop after count packet are sent, | |
// it waits either for deadline expire or until count probes | |
// are answered or for some error notification from network. | |
\sprintf('-w%d', $this->timeout), | |
// destination | |
$host, | |
]); | |
$process->setTimeout($this->timeout + 1); | |
$process->disableOutput(); | |
$process->run(); | |
return $process->isSuccessful(); | |
} | |
} |
This file contains hidden or 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
<?php | |
declare(strict_types=1); | |
namespace App\Doctrine\DBAL\Middleware\PingConnection; | |
use Doctrine\Bundle\DoctrineBundle\Attribute\AsMiddleware; | |
use Doctrine\DBAL\Driver as DriverInterface; | |
use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface; | |
#[AsMiddleware(priority: 1024)] | |
class Middleware implements MiddlewareInterface | |
{ | |
public function __construct( | |
private readonly int $timeout = 5, | |
) { | |
} | |
public function wrap(DriverInterface $driver): DriverInterface | |
{ | |
return new Driver($driver, $this->timeout); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment