hgsql: Do not succeed in syncing if we failed to take locks

Summary:
We sometimes "succeeded" in syncing to the database if we could not get local write locks, because we assumed that the only time we can't get those locks is if we're not waiting for them. However, if another process holds the local write locks and is not releasing them, we hit a timeout.

If you're doing a write operation, this is harmless - the MySQL lock ensures that only one client at a time can be syncing anyway. However, for read operations run with `--forcesync`, this can cause us to succeed without syncing, breaking our contract with our users.

Test Plan:
Run the test suite and confirm no change.

Manually take the local write locks, run against the test DB `hg log -r . --forcesync`, and confirm that we fail correctly with this change but not without it.

Confirm that even with the local locks taken, `hg log -r .` returns success

Reviewers: durham

Reviewed By: durham

Subscribers: tja, #mercurial

Differential Revision: https://phabricator.intern.facebook.com/D3976452

Tasks: 13484857

Signature: t1:3976452:1475757832:e8370819bc345ce8e1bde0b057755803adb9896c
This commit is contained in:
Simon Farnsworth 2016-10-07 05:25:21 -07:00
parent f42f6a17ec
commit 145b3a59b8

View File

@ -574,6 +574,8 @@ def wraprepo(repo):
wlock = self.wlock(wait=waitforlock)
lock = self.lock(wait=waitforlock)
except error.LockHeld:
if waitforlock:
raise
# Oh well. Don't block this non-critical read-only operation.
ui.debug("skipping sync for current operation\n")
return