1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 12:00:55 +01:00

Fix a possible deadlock in unit tests after an error

Summary:
After certain types of errors, we may deadlock when trying to destroy test databases.

Specifically, we still have connections open to, say, `phabricator_unittest_abasonaknlbaklnasb_herald` (or whatever) and MySQL sometimes (not sure exactly when?) waits for them before destorying the database.

Test Plan:
  - Added `$m = null; $m->method()` to a fixture test to force a fatal.
  - Saw consistent deadlock, with `storage destroy` never exiting.
  - Added `--trace` to the `storage destroy` command and made it use `phutil_passthru()` so I could see what was happening.
  - Saw it hang on some arbitrary database.
  - Conneced to MySQL, used `show full processlist;` to see what was wrong.
  - Saw the `DROP DATABASE ...` command waiting for locks to release on the database, and other connections still open.
  - Applied patch.
  - Saw consistent success.
  - Used `storage destroy --unittest-fixtures` to clean up extra databases.

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D14875
This commit is contained in:
epriestley 2015-12-24 06:37:33 -08:00
parent 19b2eb57a9
commit 37f1f55557

View file

@ -24,6 +24,11 @@ final class PhabricatorStorageFixtureScopeGuard extends Phobject {
public function destroy() { public function destroy() {
PhabricatorLiskDAO::popStorageNamespace(); PhabricatorLiskDAO::popStorageNamespace();
// NOTE: We need to close all connections before destroying the databases.
// If we do not, the "DROP DATABASE ..." statements may hang, waiting for
// our connections to close.
PhabricatorLiskDAO::closeAllConnections();
execx( execx(
'php %s destroy --force --namespace %s', 'php %s destroy --force --namespace %s',
$this->getStorageBinPath(), $this->getStorageBinPath(),