Skip to content

Commit

Permalink
Add pdo ping as periodic timer to avoid server gone error
Browse files Browse the repository at this point in the history
  • Loading branch information
prophet777 committed May 3, 2015
1 parent 1e797ba commit acbf88a
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 2 deletions.
32 changes: 32 additions & 0 deletions DependencyInjection/CompilerPass/PingableDriverCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;

class PingableDriverCompilerPass implements CompilerPassInterface
{
/**
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
$sessionHandler = $container->get('gos_web_socket.session_handler', Container::NULL_ON_INVALID_REFERENCE);

if(null === $sessionHandler){
return;
}

$periodicRegistryDef = $container->getDefinition('gos_web_socket.periodic.registry');

if($sessionHandler instanceof PdoSessionHandler){
$periodicRegistryDef->addMethodCall(
'addPeriodic', [new Reference('gos_web_socket.pdo.periodic_ping')]
);
}
}
}
2 changes: 2 additions & 0 deletions DependencyInjection/GosWebSocketExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public function load(array $configs, ContainerBuilder $container)
$def->addMethodCall('setSessionHandler', [
new Reference(ltrim($clientConf['session_handler'], '@')),
]);

$container->setAlias('gos_web_socket.session_handler', ltrim($clientConf['session_handler'], '@'));
}

$clientListenerDef = $container->getDefinition('gos_web_socket.client_event.listener');
Expand Down
2 changes: 2 additions & 0 deletions GosWebSocketBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Gos\Bundle\WebSocketBundle;

use Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass\PeriodicCompilerPass;
use Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass\PingableDriverCompilerPass;
use Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass\RpcCompilerPass;
use Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass\ServerCompilerPass;
use Gos\Bundle\WebSocketBundle\DependencyInjection\CompilerPass\TopicCompilerPass;
Expand All @@ -23,5 +24,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new RpcCompilerPass());
$container->addCompilerPass(new TopicCompilerPass());
$container->addCompilerPass(new PeriodicCompilerPass());
$container->addCompilerPass(new PingableDriverCompilerPass());
}
}
77 changes: 77 additions & 0 deletions Periodic/PdoPeriodicPing.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Gos\Bundle\WebSocketBundle\Periodic;

use Gos\Bundle\WebSocketBundle\Server\App\Registry\PeriodicRegistry;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

class PdoPeriodicPing implements PeriodicInterface
{
/**
* @var \PDO
*/
protected $pdo;

/**
* @var LoggerInterface|NullLogger
*/
protected $logger;

/**
* @var int|float
*/
protected $timeout;

/**
* @param PeriodicRegistry $periodicRegistry
* @param \PDO $pdo
* @param LoggerInterface $logger
*/
public function __construct(\PDO $pdo = null, LoggerInterface $logger = null)
{
$this->pdo = $pdo;
$this->logger = null === $logger ? new NullLogger() : $logger;
$this->timeout = 20;
}

/**
* @param int|float $timeout
*/
public function setTimeout($timeout)
{
$this->timeout = $timeout;
}

public function tick()
{
if(null === $this->pdo){
$this->logger->warning('Unable to ping sql server, service pdo is unavailable');
return;
}

//if connection is persistent we don't need to ping
if(true === $this->pdo->getAttribute(\PDO::ATTR_PERSISTENT)){
return;
}

try{
$this->pdo->query('SELECT 1');
$this->logger->notice('Successfully ping sql server');
}catch (\PDOException $e){
$this->logger->emergency('Sql server is gone, and unable to reconnect');

throw $e;
}
}

/**
* @return int
*/
public function getTimeout()
{
return $this->timeout;
}


}
6 changes: 6 additions & 0 deletions Resources/config/services/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,9 @@ services:
- @gos_web_socket.null.pubsub.router
- %kernel.debug%
- @?monolog.logger.websocket

gos_web_socket.pdo.periodic_ping:
class: Gos\Bundle\WebSocketBundle\Periodic\PdoPeriodicPing
arguments:
- @?pdo
- @?monolog.logger.websocket
4 changes: 2 additions & 2 deletions Server/App/Registry/PeriodicRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ class PeriodicRegistry

public function __construct()
{
$this->periodics = array();
$this->periodics = [];
}

/**
* @param PeriodicInterface $periodic
*/
public function addPeriodic(PeriodicInterface $periodic)
{
$this->periodics = $periodic;
$this->periodics[] = $periodic;
}

/**
Expand Down

0 comments on commit acbf88a

Please sign in to comment.