1
0
Fork 0
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:
epriestley 2012-07-23 19:06:58 -07:00
parent afa2dbc3dc
commit f1270315e9
6 changed files with 28 additions and 15 deletions

View file

@ -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);

View file

@ -38,6 +38,10 @@ final class AphrontIsolatedDatabaseConnection
} }
} }
public function close() {
return;
}
public function escapeString($string) { public function escapeString($string) {
return '<S>'; return '<S>';
} }

View file

@ -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

View file

@ -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;

View file

@ -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(

View file

@ -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.
} }
} }