This is an archive of the discontinued Mercurial Phabricator instance.

import: use context manager for lock, dirstateguard, transaction
ClosedPublic

Authored by martinvonz on Jun 14 2018, 7:32 PM.

Details

Summary

A tiny side-effect is that the transaction is now closed after saving
the commit message.

Diff Detail

Repository
rHG Mercurial
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

martinvonz created this revision.Jun 14 2018, 7:32 PM
yuja added a subscriber: yuja.Jun 15 2018, 8:39 AM

+ if not opts.get('no_commit'):
+ lock = repo.lock()
+ tr = repo.transaction('import')
+ dsguard = util.nullcontextmanager()
+ else:
+ lock = util.nullcontextmanager()
+ tr = util.nullcontextmanager()
+ dsguard = dirstateguard.dirstateguard(repo, 'import')
+ with lock, tr, dsguard:

Doesn't it leave a stale lock if repo.transaction() raises exception?

martinvonz updated this revision to Diff 9095.Jun 15 2018, 1:04 PM
In D3748#58738, @yuja wrote:

+ if not opts.get('no_commit'):
+ lock = repo.lock()
+ tr = repo.transaction('import')
+ dsguard = util.nullcontextmanager()
+ else:
+ lock = util.nullcontextmanager()
+ tr = util.nullcontextmanager()
+ dsguard = dirstateguard.dirstateguard(repo, 'import')
+ with lock, tr, dsguard:

Doesn't it leave a stale lock if repo.transaction() raises exception?

Good catch. I have often wished that our transactions and locks respected the context manager protocol and did the locking in enter. How do you feel about this workaround (see updated code)?

yuja added a comment.Jun 15 2018, 10:00 PM

+ if not opts.get('no_commit'):
+ lock = repo.lock()
+ try:

tr = repo.transaction('import')
  • else:
  • dsguard = dirstateguard.dirstateguard(repo, 'import')

+ except:
+ lock.release()

Needs to re-raise.

+ dsguard = util.nullcontextmanager()
+ else:
+ lock = util.nullcontextmanager()
+ tr = util.nullcontextmanager()
+ dsguard = dirstateguard.dirstateguard(repo, 'import')
+ with lock, tr, dsguard:

Another option is to wrap transaction and dirstateguard by lambda or partial,
and call them with "with".

with lock(), tr(), dsguard():
martinvonz updated this revision to Diff 9127.Jun 17 2018, 9:33 AM
In D3748#58833, @yuja wrote:

+ if not opts.get('no_commit'):
+ lock = repo.lock()
+ try:

tr = repo.transaction('import')
  • else:
  • dsguard = dirstateguard.dirstateguard(repo, 'import')

+ except:
+ lock.release()

Needs to re-raise.

+ dsguard = util.nullcontextmanager()
+ else:
+ lock = util.nullcontextmanager()
+ tr = util.nullcontextmanager()
+ dsguard = dirstateguard.dirstateguard(repo, 'import')
+ with lock, tr, dsguard:

Another option is to wrap transaction and dirstateguard by lambda or partial,
and call them with "with".

with lock(), tr(), dsguard():

Good idea. Done.

This revision was automatically updated to reflect the committed changes.