When to use invalidate()

Greg Ward greg at gerg.ca
Mon Feb 1 18:34:07 CST 2010


Hi all --

I have an extension that keeps too much data in memory.  (It's my
"bugmap" extension that associates changesets and bug IDs.  Uses a
local flat file for short-term storage and a remote MySQL database for
long-term.  It keeps a copy of the local file, a MySQL connection, and
a cache of info queried from MySQL in memory.  It uses that info to
doctor the value returned by changectx.description() so that mutable
bug IDs appear in any log output.)

This is no big deal at the command line, but I have several related
bugs that appear in long-running processes like TortoiseHg and hgweb
(I'm using mod_wsgi):

  * MySQL errors because the database connection used by the extension
stays open and the server got restarted
  * out-of-date information: someone pushes new changesets to the
repo, and hgweb correctly shows them, but bugmap fails to augment the
display with bug info (which it correctly does for changesets that
existed initially)

In all cases, the workaround is to restart the long-running process.  Lame.

I *thought* the right fix was to wrap localrepository.invalidate() and
use that to discard my extension's state.  Then on the next request,
it would re-read the local bugmap file, reopen the database
connection, etc.  But that doesn't work: hgweb doesn't even call
invalidate()!  TortoiseHg seems to call it a lot, but I have not read
the code to see when or why.

So, two questions:

1) what is the right way for an extension to discard unwanted state at
the end of a request (or similar processing phase, e.g. GUI refresh)?
2) what is the purpose of localrepository.invalidate() and when is it
normally called?

Thanks --

Greg


More information about the Mercurial-devel mailing list