Patchwork [V2] wireproto: explicitly flush stdio to prevent stalls on Windows

login
register
mail settings
Submitter Matt Harbison
Date March 11, 2018, 7:51 p.m.
Message ID <6c6b10b5d5bd617a0194.1520797884@Envy>
Download mbox | patch
Permalink /patch/29309/
State Accepted
Headers show

Comments

Matt Harbison - March 11, 2018, 7:51 p.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1520744281 18000
#      Sat Mar 10 23:58:01 2018 -0500
# Node ID 6c6b10b5d5bd617a01942974928b8b9c59eddb4a
# Parent  963b4223d14fa419df2a82fbe47cd55075707b6a
wireproto: explicitly flush stdio to prevent stalls on Windows

This is the key to fixing the hangs on Windows in D2720[1].  I put flushes in a
bunch of other places that didn't help, but I suspect that's more a lack of test
coverage than anything else.

Chasing down stuff like this is pretty painful.  I'm wondering if we can put a
proxy around sys.stderr (and sys.stdout?) on Windows (only when daemonized?)
that will flush on every write (or at least every write with a '\n').

[1] https://www.mercurial-scm.org/pipermail/mercurial-devel/2018-March/113352.html
Matt Harbison - March 18, 2018, 7:48 p.m.
On Sun, 11 Mar 2018 15:51:24 -0400, Matt Harbison <mharbison72@gmail.com>  
wrote:

> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1520744281 18000
> #      Sat Mar 10 23:58:01 2018 -0500
> # Node ID 6c6b10b5d5bd617a01942974928b8b9c59eddb4a
> # Parent  963b4223d14fa419df2a82fbe47cd55075707b6a
> wireproto: explicitly flush stdio to prevent stalls on Windows

Gentle ping on this.  While the hang in test-ssh-proto-unbundle.t with  
D2720 won't matter unless that is accepted, this fixes the unstable output  
in test-ssh-proto.t as well.
Yuya Nishihara - March 19, 2018, 1:29 p.m.
On Sun, 18 Mar 2018 15:48:12 -0400, Matt Harbison wrote:
> On Sun, 11 Mar 2018 15:51:24 -0400, Matt Harbison <mharbison72@gmail.com>  
> wrote:
> 
> > # HG changeset patch
> > # User Matt Harbison <matt_harbison@yahoo.com>
> > # Date 1520744281 18000
> > #      Sat Mar 10 23:58:01 2018 -0500
> > # Node ID 6c6b10b5d5bd617a01942974928b8b9c59eddb4a
> > # Parent  963b4223d14fa419df2a82fbe47cd55075707b6a
> > wireproto: explicitly flush stdio to prevent stalls on Windows
> 
> Gentle ping on this.  While the hang in test-ssh-proto-unbundle.t with  
> D2720 won't matter unless that is accepted, this fixes the unstable output  
> in test-ssh-proto.t as well.

Queued, thanks. I have no idea how this can solve the hang, but flushing
debug logs should be good.

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -716,11 +716,13 @@  class fileobjectobserver(object):
     def _writedata(self, data):
         if not self.logdata:
             self.fh.write('\n')
+            self.fh.flush()
             return
 
         # Simple case writes all data on a single line.
         if b'\n' not in data:
             self.fh.write(': %s\n' % escapedata(data))
+            self.fh.flush()
             return
 
         # Data with newlines is written to multiple lines.
@@ -728,6 +730,7 @@  class fileobjectobserver(object):
         lines = data.splitlines(True)
         for line in lines:
             self.fh.write('%s>     %s\n' % (self.name, escapedata(line)))
+        self.fh.flush()
 
     def read(self, res, size=-1):
         if not self.reads:
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -1069,6 +1069,7 @@  def unbundle(repo, proto, heads):
                     util.stderr.write("abort: %s\n" % exc)
                     if exc.hint is not None:
                         util.stderr.write("(%s)\n" % exc.hint)
+                    util.stderr.flush()
                     return pushres(0, output.getvalue() if output else '')
                 except error.PushRaced:
                     return pusherr(pycompat.bytestr(exc),