mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
Allow connections to be closed; close connections for global locks
Summary: Add an explicit close() method to connections and call it in GlobalLock. Test Plan: Wrote a script like this: $lock = PhabricatorGlobalLock::newLock('test'); echo "LOCK"; $lock->lock(); sleep(10); echo "UNLOCK"; $lock->unlock(); sleep(9999); Using `SHOW FULL PROCESSLIST`, verified the connection closed after 10 seconds with both the "MySQL" and "MySQLi" implementations. Reviewers: btrahan, vrana Reviewed By: vrana CC: aran Maniphest Tasks: T1470 Differential Revision: https://secure.phabricator.com/D3035
This commit is contained in:
parent
afa2dbc3dc
commit
f1270315e9
6 changed files with 28 additions and 15 deletions
|
@ -28,19 +28,20 @@ abstract class AphrontDatabaseConnection {
|
||||||
abstract public function getAffectedRows();
|
abstract public function getAffectedRows();
|
||||||
abstract public function selectAllResults();
|
abstract public function selectAllResults();
|
||||||
abstract public function executeRawQuery($raw_query);
|
abstract public function executeRawQuery($raw_query);
|
||||||
|
abstract public function close();
|
||||||
|
|
||||||
abstract public function escapeString($string);
|
abstract public function escapeString($string);
|
||||||
abstract public function escapeColumnName($string);
|
abstract public function escapeColumnName($string);
|
||||||
abstract public function escapeMultilineComment($string);
|
abstract public function escapeMultilineComment($string);
|
||||||
abstract public function escapeStringForLikeClause($string);
|
abstract public function escapeStringForLikeClause($string);
|
||||||
|
|
||||||
public function queryData($pattern/*, $arg, $arg, ... */) {
|
public function queryData($pattern/* , $arg, $arg, ... */) {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
array_unshift($args, $this);
|
array_unshift($args, $this);
|
||||||
return call_user_func_array('queryfx_all', $args);
|
return call_user_func_array('queryfx_all', $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query($pattern/*, $arg, $arg, ... */) {
|
public function query($pattern/* , $arg, $arg, ... */) {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
array_unshift($args, $this);
|
array_unshift($args, $this);
|
||||||
return call_user_func_array('queryfx', $args);
|
return call_user_func_array('queryfx', $args);
|
||||||
|
|
|
@ -38,6 +38,10 @@ final class AphrontIsolatedDatabaseConnection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function close() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public function escapeString($string) {
|
public function escapeString($string) {
|
||||||
return '<S>';
|
return '<S>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ final class AphrontMySQLDatabaseConnection
|
||||||
return mysql_affected_rows($this->requireConnection());
|
return mysql_affected_rows($this->requireConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function closeConnection() {
|
||||||
|
mysql_close($this->requireConnection());
|
||||||
|
}
|
||||||
|
|
||||||
protected function connect() {
|
protected function connect() {
|
||||||
if (!function_exists('mysql_connect')) {
|
if (!function_exists('mysql_connect')) {
|
||||||
// We have to '@' the actual call since it can spew all sorts of silly
|
// We have to '@' the actual call since it can spew all sorts of silly
|
||||||
|
|
|
@ -32,15 +32,24 @@ abstract class AphrontMySQLDatabaseConnectionBase
|
||||||
abstract protected function fetchAssoc($result);
|
abstract protected function fetchAssoc($result);
|
||||||
abstract protected function getErrorCode($connection);
|
abstract protected function getErrorCode($connection);
|
||||||
abstract protected function getErrorDescription($connection);
|
abstract protected function getErrorDescription($connection);
|
||||||
|
abstract protected function closeConnection();
|
||||||
|
|
||||||
public function __construct(array $configuration) {
|
public function __construct(array $configuration) {
|
||||||
$this->configuration = $configuration;
|
$this->configuration = $configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function close() {
|
||||||
|
if ($this->connection) {
|
||||||
|
$this->closeConnection();
|
||||||
|
$this->connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function escapeColumnName($name) {
|
public function escapeColumnName($name) {
|
||||||
return '`'.str_replace('`', '``', $name).'`';
|
return '`'.str_replace('`', '``', $name).'`';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function escapeMultilineComment($comment) {
|
public function escapeMultilineComment($comment) {
|
||||||
// These can either terminate a comment, confuse the hell out of the parser,
|
// These can either terminate a comment, confuse the hell out of the parser,
|
||||||
// make MySQL execute the comment as a query, or, in the case of semicolon,
|
// make MySQL execute the comment as a query, or, in the case of semicolon,
|
||||||
|
@ -78,12 +87,6 @@ abstract class AphrontMySQLDatabaseConnectionBase
|
||||||
return idx($this->configuration, $key, $default);
|
return idx($this->configuration, $key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function closeConnection() {
|
|
||||||
if ($this->connection) {
|
|
||||||
$this->connection = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function establishConnection() {
|
private function establishConnection() {
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
|
|
||||||
|
@ -189,12 +192,12 @@ abstract class AphrontMySQLDatabaseConnectionBase
|
||||||
// We can't close the connection before this because
|
// We can't close the connection before this because
|
||||||
// isInsideTransaction() and getTransactionState() depend on the
|
// isInsideTransaction() and getTransactionState() depend on the
|
||||||
// connection.
|
// connection.
|
||||||
$this->closeConnection();
|
$this->close();
|
||||||
|
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->closeConnection();
|
$this->close();
|
||||||
|
|
||||||
if (!$retries) {
|
if (!$retries) {
|
||||||
throw $ex;
|
throw $ex;
|
||||||
|
|
|
@ -36,6 +36,10 @@ final class AphrontMySQLiDatabaseConnection
|
||||||
return $this->requireConnection()->affected_rows;
|
return $this->requireConnection()->affected_rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function closeConnection() {
|
||||||
|
$this->requireConnection()->close();
|
||||||
|
}
|
||||||
|
|
||||||
protected function connect() {
|
protected function connect() {
|
||||||
if (!class_exists('mysqli', false)) {
|
if (!class_exists('mysqli', false)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
|
@ -110,11 +110,8 @@ final class PhabricatorGlobalLock extends PhutilLock {
|
||||||
'SELECT RELEASE_LOCK(%s)',
|
'SELECT RELEASE_LOCK(%s)',
|
||||||
'phabricator:'.$this->lockname);
|
'phabricator:'.$this->lockname);
|
||||||
|
|
||||||
// TODO: There's no explicit close() method on connections right now. Once
|
$this->conn->close();
|
||||||
// we have one, we could close the connection here. Since we don't have
|
$this->conn = null;
|
||||||
// such a method, we need to keep the connection around in case lock() is
|
|
||||||
// called again, so that long-running daemons don't gradually open
|
|
||||||
// an unbounded number of connections.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue