mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-15 05:53:13 +00:00
Add reconnectable connection
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Command\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Thesaurus;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@@ -13,7 +13,7 @@ namespace Alchemy\Phrasea\Core\Connection;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
|
||||
class ConnectionProvider
|
||||
@@ -58,6 +58,6 @@ class ConnectionProvider
|
||||
return $this->connections[$key];
|
||||
}
|
||||
|
||||
return $this->connections[$key] = DriverManager::getConnection($params, $this->config, $this->eventManager);;
|
||||
return $this->connections[$key] = new ReconnectableConnection(DriverManager::getConnection($params, $this->config, $this->eventManager));
|
||||
}
|
||||
}
|
||||
|
146
lib/Alchemy/Phrasea/Core/Connection/ReconnectableConnection.php
Normal file
146
lib/Alchemy/Phrasea/Core/Connection/ReconnectableConnection.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Connection;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
|
||||
class ReconnectableConnection implements ConnectionInterface
|
||||
{
|
||||
const MYSQL_CONNECTION_TIMED_WAIT_CODE = 2006;
|
||||
|
||||
/** @var Connection */
|
||||
private $connection;
|
||||
|
||||
public function __construct(ConnectionInterface $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function prepare($prepareString)
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function query()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function quote($input, $type=\PDO::PARAM_STR)
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function exec($statement)
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function lastInsertId($name = null)
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function beginTransaction()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function rollBack()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function errorCode()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function errorInfo()
|
||||
{
|
||||
return $this->tryMethod(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
return $this->tryMethod($method, $args);
|
||||
}
|
||||
|
||||
private function tryMethod($method, $args)
|
||||
{
|
||||
try {
|
||||
set_error_handler(function ($errno, $errstr) { throw new \Exception($errstr, $errno); });
|
||||
$ret = call_user_func_array([$this->connection, $method], $args);
|
||||
restore_error_handler();
|
||||
|
||||
return $ret;
|
||||
} catch (\Exception $exception) {
|
||||
restore_error_handler();
|
||||
$e = $exception;
|
||||
while ($e->getPrevious() && !$e instanceof \PDOException) {
|
||||
$e = $e->getPrevious();
|
||||
}
|
||||
if ($e instanceof \PDOException && $e->errorInfo[1] == self::MYSQL_CONNECTION_TIMED_WAIT_CODE) {
|
||||
$this->connection->close();
|
||||
$this->connection->connect();
|
||||
|
||||
return call_user_func_array([$this->connection, $method], $args);
|
||||
}
|
||||
if ((false !== strpos($exception->getMessage(), 'MySQL server has gone away')) || (false !== strpos($exception->getMessage(), 'errno=32 Broken pipe'))) {
|
||||
$this->connection->close();
|
||||
$this->connection->connect();
|
||||
|
||||
return call_user_func_array([$this->connection, $method], $args);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@ namespace Alchemy\Phrasea\Model\Manager;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Model\Entities\UserSetting;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\ORM\UnitOfWork AS UOW;
|
||||
|
||||
class UserManager
|
||||
|
@@ -12,7 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
|
@@ -13,7 +13,7 @@ use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Version as PhraseaVersion;
|
||||
use vierbergenlars\SemVer\version;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
abstract class base implements cache_cacheableInterface
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class collection implements cache_cacheableInterface
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
@@ -13,7 +13,7 @@ use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Vocabulary;
|
||||
use Alchemy\Phrasea\Vocabulary\ControlProvider\ControlProviderInterface;
|
||||
use Alchemy\Phrasea\Metadata\Tag\Nosource;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use PHPExiftool\Driver\TagInterface;
|
||||
use PHPExiftool\Driver\TagFactory;
|
||||
use PHPExiftool\Exception\TagUnknown;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_100 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_200 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_201 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_202 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_203 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
class patchthesaurus_204 implements patchthesaurus_interface
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
|
||||
interface patchthesaurus_interface
|
||||
{
|
||||
|
@@ -84,7 +84,7 @@ class InstallTest extends \PhraseanetTestCase
|
||||
|
||||
self::$DI['cli']['phraseanet.installer']->expects($this->once())
|
||||
->method('install')
|
||||
->with($email, $password, $this->isInstanceOf('Doctrine\DBAL\Connection'), $serverName, $dataPath, $this->isInstanceOf('Doctrine\DBAL\Connection'), $template, $this->anything());
|
||||
->with($email, $password, $this->isInstanceOf('Doctrine\DBAL\Driver\Connection'), $serverName, $dataPath, $this->isInstanceOf('Doctrine\DBAL\Driver\Connection'), $template, $this->anything());
|
||||
|
||||
$command = new Install('system:check');
|
||||
$command->setHelperSet($helperSet);
|
||||
|
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Core\Connection;
|
||||
|
||||
use Alchemy\Phrasea\Core\Connection\ConnectionProvider;
|
||||
|
||||
class ConnectionProviderTest extends \PhraseanetTestCase
|
||||
{
|
||||
public function testMysqlTimeoutIsHandled()
|
||||
{
|
||||
$provider = new ConnectionProvider(self::$DI['app']['EM.config'], self::$DI['app']['EM.events-manager']);
|
||||
$conn = $provider->get(self::$DI['app']['conf']->get(['main', 'database']));
|
||||
$conn->exec('SET @@local.wait_timeout= 1');
|
||||
usleep(1200000);
|
||||
$conn->exec('SHOW DATABASES');
|
||||
}
|
||||
}
|
@@ -112,7 +112,7 @@ class collectionTest extends \PhraseanetAuthenticatedTestCase
|
||||
|
||||
public function testGet_connection()
|
||||
{
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Connection', self::$object->get_connection());
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Driver\Connection', self::$object->get_connection());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -70,8 +70,8 @@ class databox_fieldTest extends \PhraseanetTestCase
|
||||
|
||||
public function testGet_connection()
|
||||
{
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Connection', $this->object_mono->get_connection());
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Connection', $this->object_multi->get_connection());
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Driver\Connection', $this->object_mono->get_connection());
|
||||
$this->assertInstanceOf('Doctrine\DBAL\Driver\Connection', $this->object_multi->get_connection());
|
||||
}
|
||||
|
||||
public function testGet_databox()
|
||||
|
Reference in New Issue
Block a user