These are downstream patches from: https://github.com/python-progress/python-progress/pull/1 Per recent discussions, this seems to be fixed for latest verigak/progress upstream too, OTOH upstream changed API probably -- so once we are there, we could revert those: https://github.com/verigak/progress/issues/34 Resolves: rhbz#1299634
87 lines
2.8 KiB
Diff
87 lines
2.8 KiB
Diff
From 4691a1efdcd8cbe4bc66d586307daf6505f21db4 Mon Sep 17 00:00:00 2001
|
|
From: Pavel Raiskup <praiskup@redhat.com>
|
|
Date: Mon, 18 Jan 2016 19:05:25 +0100
|
|
Subject: [PATCH 2/2] make the progress bar more stable
|
|
|
|
Add new sma_delta parameter. That parameter represents time delta
|
|
(in seconds) for which _one item_ in deque() is valid until we
|
|
create new one. Practically, one item represents number of items
|
|
processed during 'sma_delta' time (by default 0.3s).
|
|
|
|
Taking into account sma_delta and sma_window values, progress bar
|
|
now returns statistics for the last (sma_delta*sma_window)
|
|
seconds, which is by default 3s.
|
|
|
|
Document a bit.
|
|
|
|
This resolves verigak/progress/pull/24.
|
|
---
|
|
progress/__init__.py | 43 +++++++++++++++++++++++++++++++++++++++++--
|
|
1 file changed, 41 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/progress/__init__.py b/progress/__init__.py
|
|
index 3130fe1..37b4547 100644
|
|
--- a/progress/__init__.py
|
|
+++ b/progress/__init__.py
|
|
@@ -24,9 +24,35 @@ from time import time
|
|
__version__ = '1.2'
|
|
|
|
|
|
+"""
|
|
+The moving average is calculated by this formula:
|
|
+
|
|
+ _in_window / (time() - oldest_timestamp_in_window)
|
|
+
|
|
+Because the frequency of calling next() callback might be rather very high,
|
|
+doing the naive next()/avg() implementation leads to issues (PR 23):
|
|
+
|
|
+ def next(N):
|
|
+ t = time()
|
|
+ delta = N / (t - last_timestamp) # very small number
|
|
+ _dt.append(delta)
|
|
+ _avg = sum(_dt)/len(_dt)
|
|
+ last_timestamp = t
|
|
+
|
|
+.. Even if 'len(_dt)' was 1000, the time frame can be very small (e.g. file
|
|
+download for next(N=8k in bytes) on 1Gbit network. With the mentioned formula
|
|
+the window size is limited by *time*, not by the next() callback frequency.
|
|
+
|
|
+The moving average is calculated -at most- for the last 3 seconds by default:
|
|
+
|
|
+ sma_window x sma_delta = 10 x 0.3 = 3s
|
|
+
|
|
+Users can change this default window size, when needed.
|
|
+"""
|
|
class Infinite(object):
|
|
file = stderr
|
|
- sma_window = 10
|
|
+ sma_window = 10 # Size of the window -- (max) number of sma_delta items.
|
|
+ sma_delta = 0.3 # Time-length of one item in window, in seconds.
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.index = 0
|
|
@@ -67,7 +93,20 @@ class Infinite(object):
|
|
|
|
def next(self, n=1):
|
|
self._ts = time()
|
|
- self._dt.append({'t': self._ts, 'n': n})
|
|
+
|
|
+ item = {'t': self._ts, 'n': 0}
|
|
+ if len(self._dt):
|
|
+ old_item = self._dt.pop()
|
|
+ if self._ts > old_item['t'] + self.sma_delta:
|
|
+ # Already reached timeout, we are not going to
|
|
+ # touch this item. Return it back.
|
|
+ self._dt.append(old_item)
|
|
+ else:
|
|
+ item = old_item
|
|
+
|
|
+ item['n'] = item['n'] + n
|
|
+
|
|
+ self._dt.append(item)
|
|
self._in_window = self._in_window + n
|
|
|
|
if len(self._dt) > self.sma_window:
|
|
--
|
|
2.7.4
|
|
|