Bug 3301 - Extension.py not thread safe
Summary: Extension.py not thread safe
Status: RESOLVED WONTFIX
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: wish feature
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-02 00:36 UTC by tkruse
Modified: 2012-05-13 04:49 UTC (History)
5 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description tkruse 2012-03-02 00:36 UTC
Hi, I am writing a python script that manages several repositories, and I
ran into issues with the mercurial API. I am running 
$ hg --version
Mercurial Distributed SCM (version 1.4.3) on Ubuntu Lucid.

Every now and then I get Exceptions, when running the same command.
Exceptions look like below:

File
"/usr/local/lib/python2.6/dist-packages/vcstools-0.1.5-py2.6.egg/vcstools/hg.py",
line 260, in _get_hg_repo
    return hg.repository(ui = ui.ui(), path = path)
  File "/usr/lib/pymodules/python2.6/mercurial/hg.py", line 63, in repository
    repo = _lookup(path).instance(ui, path, create)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 2151, in
instance
    return localrepository(ui, util.drop_scheme('file', path), create)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 37, in
__init__
    extensions.loadall(self.ui)
  File "/usr/lib/pymodules/python2.6/mercurial/extensions.py", line 94, in
loadall
    uisetup(ui)
  File "/usr/lib/pymodules/python2.6/hgext/graphlog.py", line 354, in uisetup
    _wrapcmd(ui, 'log', commands.table, graphlog)
  File "/usr/lib/pymodules/python2.6/hgext/graphlog.py", line 364, in _wrapcmd
    entry = extensions.wrapcommand(table, cmd, graph)
  File "/usr/lib/pymodules/python2.6/mercurial/extensions.py", line 123, in
wrapcommand
    table[key] = tuple(newentry)
UnboundLocalError: local variable 'key' referenced before assignment

return hg.repository(ui = ui.ui(), path = path)
  File "/usr/lib/pymodules/python2.6/mercurial/hg.py", line 63, in repository
    repo = _lookup(path).instance(ui, path, create)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 2151, in
instance
    return localrepository(ui, util.drop_scheme('file', path), create)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 37, in
__init__
    extensions.loadall(self.ui)
  File "/usr/lib/pymodules/python2.6/mercurial/extensions.py", line 100, in
loadall
    extsetup(ui)
  File "/usr/lib/pymodules/python2.6/hgext/color.py", line 261, in extsetup
    _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
  File "/usr/lib/pymodules/python2.6/hgext/color.py", line 282, in _setupcmd
    entry = extensions.wrapcommand(table, cmd, nocolor)
  File "/usr/lib/pymodules/python2.6/mercurial/extensions.py", line 107, in
wrapcommand
    aliases, entry = cmdutil.findcmd(command, table)
  File "/usr/lib/pymodules/python2.6/mercurial/cmdutil.py", line 60, in findcmd
    raise error.UnknownCommand(cmd)
UnknownCommand: qrecord

In those cases I had 5 threads working on distinct (separate sibling
folders) mercurial repositories. The threads would all do:

class HackedHgUI():
    def __init__(self, ui):
        self.output = ''
        ui.write = self.write
    def write(self, output, label = None):
        self.output += output

r =  hg.repository(ui = ui.ui(), path = path)
if r is None:
  return None
fakeui = HackedHgUI(r.ui)
commands.status(ui = r.ui,
  repo = r,
  git = True,
  modified = not untracked,
  added=not untracked,
  removed=not untracked,
  deleted=not untracked)


The threads do not call any other mercurial API functions.

I had several extentions set up:
hgext.graphlog =
bookmarks=
hgext.record=
hgext.bookmarks=
hgk=
color=
hggit=
transplant=
mq=
rebase=
patchbomb=

My script runs fine about 19 times out of 20 on my machine.

I hope this is sufficient for you to confirm and fix the bug, if not already
fixed in more recent versions. I guess I will just have to serialize my
calls, as I have to rely on existing mercurial versions.
Comment 1 kiilerix 2012-03-02 03:47 UTC
The internal Mercurial API do not make any attempt to be thread-safe. If you
use it in your own way in a multi-threaded application then you need to do
some kind of locking. Using separate processes will probably be simpler.

The recommended and stable way to integrate with Mercurial is to use the
command line interface or http://mercurial.selenic.com/wiki/CommandServer .

Changing priority to wish.
Comment 2 Matt Mackall 2012-03-02 11:50 UTC
Won't fix.
Comment 3 Bugzilla 2012-05-12 09:28 UTC

--- Bug imported by bugzilla@serpentine.com 2012-05-12 09:28 EDT  ---

This bug was previously known as _bug_ 3300 at http://mercurial.selenic.com/bts/issue3300