[PATCH 3 of 3] progress: add a changedelay to prevent parallel topics from flapping (issue2698)

Augie Fackler durin42 at gmail.com
Sun Jul 3 09:55:31 CDT 2011


# HG changeset patch
# User Augie Fackler <durin42 at gmail.com>
# Date 1308859245 18000
# Node ID b38da1bcd5e02d584bfed674386c2fa36c566e6c
# Parent  eb39d79604093aaa7696f573e98128c7d0bcc31f
progress: add a changedelay to prevent parallel topics from flapping (issue2698)

When combined with the earlier change to make the progress object
truly a singleton, this prevents the progress bar swapping on 'hg
clone --pull' on a local filesystem.

Thanks to timeless for lots of debugging help at the Copenhagen sprint
to isolate the root cause of this and a first draft an idea that would
fix it.

diff --git a/hgext/progress.py b/hgext/progress.py
--- a/hgext/progress.py
+++ b/hgext/progress.py
@@ -27,6 +27,9 @@
 
   [progress]
   delay = 3 # number of seconds (float) before showing the progress bar
+  changedelay = 1 # changedelay: minimum delay before showing a new topic.
+                  # If set to less than 3 * refresh, that value will
+                  # be used instead.
   refresh = 0.1 # time in seconds between refreshes of the progress bar
   format = topic bar number estimate # format of the progress bar
   width = <none> # if set, the maximum width of the progress information
@@ -105,9 +108,13 @@
         self.printed = False
         self.lastprint = time.time() + float(self.ui.config(
             'progress', 'delay', default=3))
+        self.lasttopic = None
         self.indetcount = 0
         self.refresh = float(self.ui.config(
             'progress', 'refresh', default=0.1))
+        self.changedelay = max(3 * self.refresh,
+                               float(self.ui.config(
+                                   'progress', 'changedelay', default=1)))
         self.order = self.ui.configlist(
             'progress', 'format',
             default=['topic', 'bar', 'number', 'estimate'])
@@ -184,6 +191,7 @@
         else:
             out = spacejoin(head, tail)
         sys.stderr.write('\r' + out[:termwidth])
+        self.lasttopic = topic
         sys.stderr.flush()
 
     def clear(self):
@@ -248,8 +256,13 @@
                 self.topics.append(topic)
             self.topicstates[topic] = pos, item, unit, total
             if now - self.lastprint >= self.refresh and self.topics:
-                self.lastprint = now
-                self.show(now, topic, *self.topicstates[topic])
+                if (self.lasttopic is None # first time we printed
+                    # not a topic change
+                    or topic == self.lasttopic
+                    # it's been long enough we should print anyway
+                    or now - self.lastprint >= self.changedelay):
+                    self.lastprint = now
+                    self.show(now, topic, *self.topicstates[topic])
 
 _singleton = None
 
diff --git a/tests/test-convert-svn-move.t b/tests/test-convert-svn-move.t
--- a/tests/test-convert-svn-move.t
+++ b/tests/test-convert-svn-move.t
@@ -167,6 +167,7 @@
   > [progress]
   > assume-tty = 1
   > delay = 0
+  > changedelay = 0
   > format = topic bar number
   > refresh = 0
   > width = 60
diff --git a/tests/test-progress.t b/tests/test-progress.t
--- a/tests/test-progress.t
+++ b/tests/test-progress.t
@@ -9,16 +9,28 @@
   >         total = loops
   >     if opts.get('total', None):
   >         total = int(opts.get('total'))
+  >     nested = False
+  >     if opts.get('nested', None):
+  >         nested = True
   >     loops = abs(loops)
   > 
   >     for i in range(loops):
   >         ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
+  >         if opts.get('parallel'):
+  >             ui.progress('other', i, 'other.%d' % i, 'othernum', total)
+  >         if nested:
+  >             for j in range(2):
+  >                 ui.progress('nested', j, 'nested.%d' % j, 'nestnum', 2)
+  >             ui.progress('nested', None, 'nested.done', 'nestnum', 2)
   >     ui.progress('loop', None, 'loop.done', 'loopnum', total)
   > 
   > commands.norepo += " loop"
   > 
   > cmdtable = {
-  >     "loop": (loop, [('', 'total', '', 'override for total')],
+  >     "loop": (loop, [('', 'total', '', 'override for total'),
+  >                     ('', 'nested', False, 'show nested results'),
+  >                     ('', 'parallel', False, 'show parallel sets of results'),
+  >                    ],
   >              'hg loop LOOPS'),
   > }
   > EOF
@@ -47,6 +59,42 @@
   loop [===============================>                ] 2/3
                                                               \r (esc)
 
+
+test nested short-lived topics (which shouldn't display with nestdelay):
+
+  $ hg -y loop 3 --nested 2>&1 | \
+  > python $TESTDIR/filtercr.py
+  
+  loop [                                                ] 0/3
+  loop [===============>                                ] 1/3
+  loop [===============================>                ] 2/3
+                                                              \r (esc)
+
+
+  $ hg --config progress.changedelay=0 -y loop 3 --nested 2>&1 | \
+  > python $TESTDIR/filtercr.py
+  
+  loop [                                                ] 0/3
+  nested [                                              ] 0/2
+  nested [======================>                       ] 1/2
+  loop [===============>                                ] 1/3
+  nested [                                              ] 0/2
+  nested [======================>                       ] 1/2
+  loop [===============================>                ] 2/3
+  nested [                                              ] 0/2
+  nested [======================>                       ] 1/2
+                                                              \r (esc)
+
+
+test two topics being printed in parallel (as when we're doing a local
+--pull clone, where you get the unbundle and bundle progress at the
+same time):
+  $ hg loop 3 --parallel 2>&1 | python $TESTDIR/filtercr.py
+  
+  loop [                                                ] 0/3
+  loop [===============>                                ] 1/3
+  loop [===============================>                ] 2/3
+                                                              \r (esc)
 test refresh is taken in account
 
   $ hg -y --config progress.refresh=100 loop 3 2>&1 | $TESTDIR/filtercr.py


More information about the Mercurial-devel mailing list