[PATCHv2] Add timeout to callbacks waiting for enough entropy (#1073679)
Vratislav Podzimek
vpodzime at redhat.com
Wed Nov 5 08:28:53 UTC 2014
On Tue, 2014-11-04 at 09:29 -0500, Anne Mulhern wrote:
> > diff --git a/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py
> > b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py
> > index d04b08d..3ad1c74 100644
> > --- a/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py
> > +++ b/pyanaconda/ui/gui/spokes/lib/entropy_dialog.py
> > @@ -20,15 +20,21 @@
> > #
> >
> > import time
> > +import math
> >
> > from gi.repository import Gtk, GLib
> >
> > +from pyanaconda.i18n import P_
> > +from pyanaconda.constants import MAX_ENTROPY_WAIT
> > from pyanaconda.ui.gui import GUIObject
> > from pyanaconda.ui.gui.utils import gtk_action_wait
> > from blivet.util import get_current_entropy
> >
> > __all__ = ["run_entropy_dialog"]
> >
> > +# in milliseconds
> > +LOOP_TIMEOUT = 250
> > +
> > @gtk_action_wait
> > def run_entropy_dialog(ksdata, desired_entropy):
> > """Show dialog with waiting for entropy"""
> > @@ -36,6 +42,8 @@ def run_entropy_dialog(ksdata, desired_entropy):
> > dialog = EntropyDialog(ksdata, desired_entropy)
> > dialog.run()
> >
> > + return dialog.force_cont
> > +
> > class EntropyDialog(GUIObject):
> > builderObjects = ["entropyDialog"]
> > mainWidgetName = "entropyDialog"
> > @@ -46,10 +54,17 @@ class EntropyDialog(GUIObject):
> > self._desired_entropy = desired_entropy
> > self._progress_bar = self.builder.get_object("progressBar")
> > self._terminate = False
> > + self._started = 0
> > + self.force_cont = False
>
> I guess the pylint error about initializing attributes outside the constructor
> must be suppressed in anaconda, but it still seems to me that it would be reasonable
> to define self._num_loops here.
Fixing locally.
>
> >
> > def run(self):
> > self.window.show_all()
> > - GLib.timeout_add(250, self._update_progress)
> > +
> > + # XXX: Is it better to rely on Gtk running the self._update_progress
> > + # method every ~250msec or rely on NTP not changing system time
> > right
> > + # now and use time.time()?
> > + self._num_loops = 0
> > + GLib.timeout_add(LOOP_TIMEOUT, self._update_progress)
> > Gtk.main()
> > self.window.destroy()
> >
> > @@ -61,13 +76,21 @@ class EntropyDialog(GUIObject):
> > # remove the method from idle queue
> > return False
> > else:
> > + self._num_loops += 1
> > current_entropy = get_current_entropy()
> > current_fraction = min(float(current_entropy) /
> > self._desired_entropy, 1.0)
> > + remaining = (MAX_ENTROPY_WAIT - self._num_loops / (1000 /
> > LOOP_TIMEOUT)) / 60.0
>
> remaining is probably better like this:
>
> remaining = (MAX_ENTROPY_WAIT - self._num_loops * (LOOP_TIMEOUT / 1000.0)) / 60.0
>
> Note that you need to make 1000 non-integer to get the fractional quantity. Decimal
> would do just as well, but the precision is unnecessary.
>
> In your versionn:
>
> 1000 / LOOP_TIMEOUT is a correct value if 1000 is divisible by LOOP_TIMEOUT, as it
> is now, but will not work correctly if the value of LOOP_TIMEOUT changes to any non-divisor
> of 1000. So, really, it is necessary to make 1000 a fractional quantity in that version as well.
>
> Alternatively you could get the difference in milliseconds, divide by 1000 to get whole
> seconds, and then divide by 60.0 to get fractional minutes as:
>
> (MAX_ENTROPY_WAIT * 1000 - self._num_loops * LOOP_TIMEOUT) / 1000 / 60.0
>
> That seems the clearest approach to me.
Honestly, I don't care too much. Using this version in a local copy.
>
> > +
> > self._progress_bar.set_fraction(current_fraction)
> > + self._progress_bar.set_text("%(pct)d %% (%(rem)d %(min)s
> > remaining)" % {"pct": (int(current_fraction * 100)),
> > +
> > "rem":
> > math.ceil(remaining),
> > +
> > "min":
> > P_("minute", "minutes", int(remaining))})
> > +
> > + # if we have enough our time ran out, terminate the dialog, but
> > let
> > + # the progress_bar refresh in the main loop
> > + self._terminate = (current_entropy >= self._desired_entropy) or
> > (remaining <= 0)
> >
> > - # if we have enough, terminate the dialog, but let the
> > progress_bar
> > - # refresh in the main loop
> > - self._terminate = current_entropy >= self._desired_entropy
> > + self.force_cont = (remaining <= 0)
> >
> > # keep updating
> > return True
> > diff --git a/pyanaconda/ui/lib/entropy.py b/pyanaconda/ui/lib/entropy.py
> > index 1fe5634..451f093 100644
> > --- a/pyanaconda/ui/lib/entropy.py
> > +++ b/pyanaconda/ui/lib/entropy.py
> > @@ -28,12 +28,14 @@ import time
> > import select
> > import sys
> > import termios
> > +import math
> >
> > from pyanaconda.progress import progress_message
> > +from pyanaconda.constants import MAX_ENTROPY_WAIT
> > from pykickstart.constants import DISPLAY_MODE_GRAPHICAL
> > from blivet.util import get_current_entropy
> >
> > -from pyanaconda.i18n import _
> > +from pyanaconda.i18n import _, P_
> >
> > def wait_for_entropy(msg, desired_entropy, ksdata):
> > """
> > @@ -43,6 +45,8 @@ def wait_for_entropy(msg, desired_entropy, ksdata):
> > :type ksdata: pykickstart.base.BaseHandler
> > :param desired_entropy: entropy level to wait for
> > :type desired_entropy: int
> > + :returns: whether to force continuing regardless of the available
> > entropy level
> > + :rtype: bool
> >
> > """
> >
> > @@ -51,15 +55,17 @@ def wait_for_entropy(msg, desired_entropy, ksdata):
> > # in some cases
> > from pyanaconda.ui.gui.spokes.lib.entropy_dialog import
> > run_entropy_dialog
> > progress_message(_("The system needs more random data entropy"))
> > - run_entropy_dialog(ksdata, desired_entropy)
> > + return run_entropy_dialog(ksdata, desired_entropy)
> > else:
> > - _tui_wait(msg, desired_entropy)
> > + return _tui_wait(msg, desired_entropy)
> >
> > def _tui_wait(msg, desired_entropy):
> > """Tell user we are waiting for entropy"""
> >
> > print(msg)
> > print(_("Entropy can be increased by typing randomly on keyboard"))
> > + print(_("After %d minutes, the installation will continue regardless of
> > the "
> > + "amount of available entropy") % MAX_ENTROPY_WAIT)
>
> divide MAX_ENTROPY_WAIT here by 60 in some way in order to get minutes.
Good catch. I was sure I'll forgot to do it somewhere. Fixing locally.
--
Vratislav Podzimek
Anaconda Rider | Red Hat, Inc. | Brno - Czech Republic
More information about the anaconda-patches
mailing list