[PATCH 1 of 2 V2] log: flush stdout/err for the first log entries

Yuya Nishihara yuya at tcha.org
Sun Sep 27 15:15:36 UTC 2015


On Sat, 26 Sep 2015 15:45:45 -0700, Pierre-Yves David wrote:
> On 09/26/2015 01:03 AM, Yuya Nishihara wrote:
> > On Fri, 25 Sep 2015 13:08:09 -0500, Matt Mackall wrote:
> >>>> diff -r b80b2ee71a08 mercurial/ui.py
> >>>> --- a/mercurial/ui.py	Thu Sep 24 00:34:15 2015 -0700
> >>>> +++ b/mercurial/ui.py	Thu Sep 24 17:45:42 2015 -0500
> >>>> @@ -104,6 +104,7 @@
> >>>>            self._ucfg = config.config() # untrusted
> >>>>            self._trustusers = set()
> >>>>            self._trustgroups = set()
> >>>> +        self._outcount = 0
> >>>>            self.callhooks = True
> >>>>
> >>>>            if src:
> >>>> @@ -617,6 +618,9 @@
> >>>>            else:
> >>>>                for a in args:
> >>>>                    self.fout.write(str(a))
> >>>> +            if self._outcount < 50:
> >>>> +                self.fout.flush()
> >>>> +                self._outcount += 1
> >>>>
> >>>>        def write_err(self, *args, **opts):
> >>>>            self._progclear()
> >>>>
> >>>> ("hg log -k sullivan -T." is a pretty good behavior test here.)
> >
> > So we want line-buffering for first 50 lines?
> >
> > I've timed it with line-buffered stdout. It's slightly slower than fully-
> > buffered io, but perhaps we don't care it if we use the pager.
> 
> Look slike you got your hand on the way to control the buffer setting. \o/
> 
> We should definitely goes for line (or probably even none) buffering for 
> the pager pipe (the same as what we do for no-pager).

Okay, I'll look for the best way to control the buffering. IIRC, the buffer
resides in FILE API of libc as of Python 2. There are several ways to change it.

 a) sys.stdout = fdopen(sys.stdout.fileno(), 'wb', 1)  # 1 for line buffering

    can't replace all FILE* objects because sys.stdout may be aliased to
    different names, such as ui.fout.

 b) sys.stdout.write(harmless_data); sys.stdout.flush()  # before dup2()

    just a hack, but works.

 c) setvbuf(fp, NULL, _IOLBF, 0)

    platform dependent, might not work on Python 3?

    https://bitbucket.org/yuja/chg/src/fc5fb9964bda/hgext/chgutil.c#chgutil.c-78

 d) PyFile_SetBufSize(fp, 1)

    the doc says it should be called immediately after file object creation.

    https://docs.python.org/2.7/c-api/file.html#c.PyFile_SetBufSize



More information about the Mercurial-devel mailing list