Patchwork [2,of,8] blackbox: avoid creating multiple file handles for a single log

login
register
mail settings
Submitter timeless@mozdev.org
Date Feb. 24, 2016, 8:10 p.m.
Message ID <ea7682ce235c1eeace3d.1456344646@waste.org>
Download mbox | patch
Permalink /patch/13367/
State Accepted
Headers show

Comments

timeless@mozdev.org - Feb. 24, 2016, 8:10 p.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1454514091 0
#      Wed Feb 03 15:41:31 2016 +0000
# Node ID ea7682ce235c1eeace3db54238f6cfd0317f577f
# Parent  c2ebc41e7a5cf95ffd2f7dea16492ac7a1102a30
blackbox: avoid creating multiple file handles for a single log

There are multiple ui objects in Mercurial that can relate to a repository,
before this change, each one would have its own file pointer, which
results in unfortunate logging behavior.

Also, any log rotation results would be bad because only the
active blackboxui object's file pointer would be refreshed.

Note that this does not prevent two long running hg commands for the same
repository from causing problems.

Patch

diff --git a/hgext/blackbox.py b/hgext/blackbox.py
--- a/hgext/blackbox.py
+++ b/hgext/blackbox.py
@@ -49,6 +49,21 @@ 
 testedwith = 'internal'
 lastblackbox = None
 
+filehandles = {}
+
+def _openlog(vfs):
+    path = vfs.join('blackbox.log')
+    if path in filehandles:
+        return filehandles[path]
+    filehandles[path] = fp = vfs('blackbox.log', 'a')
+    return fp
+
+def _closelog(vfs):
+    path = vfs.join('blackbox.log')
+    fp = filehandles[path]
+    del filehandles[path]
+    fp.close()
+
 def wrapui(ui):
     class blackboxui(ui.__class__):
         @util.propertycache
@@ -71,20 +86,20 @@ 
                         self.debug("warning: cannot rename '%s' to '%s': %s\n" %
                                    (newpath, oldpath, err.strerror))
 
-            fp = self._bbvfs('blackbox.log', 'a')
+            fp = _openlog(self._bbvfs)
             maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
             if maxsize > 0:
                 st = self._bbvfs.fstat(fp)
                 if st.st_size >= maxsize:
                     path = fp.name
-                    fp.close()
+                    _closelog(self._bbvfs)
                     maxfiles = self.configint('blackbox', 'maxfiles', 7)
                     for i in xrange(maxfiles - 1, 1, -1):
                         rotate(oldpath='%s.%d' % (path, i - 1),
                                newpath='%s.%d' % (path, i))
                     rotate(oldpath=path,
                            newpath=maxfiles > 0 and path + '.1')
-                    fp = self._bbvfs('blackbox.log', 'a')
+                    fp = _openlog(self._bbvfs)
             return fp
 
         def log(self, event, *msg, **opts):