[PATCH] Make the Welcome spoke wait for Geolocation lookup to finish (#975193)
Martin Kolman
mkolman at redhat.com
Fri Jun 28 14:28:35 UTC 2013
The GeoIP lookup usually takes between 1 to 2 seconds to finish.
In some cases, such as when running on a live system, the welcome spoke
might show up before the lookup can finish, so the result of the lookup
can not be used to pre-set the language.
To improve this, the geoloc module top level functions now have an
optional wait parameter, that makes the function block until the
lookup is is done or a timeout is reached.
The end result is, that the Welcome spoke will wait up to 3 seconds
for the lookup to finish. Usually it would wait less than 2 seconds or
not at all (if the lookup finishes before the welcome spoke is even
initialized).
Signed-off-by: Martin Kolman <mkolman at gmail.com>
---
pyanaconda/constants.py | 3 ++
pyanaconda/geoloc.py | 62 ++++++++++++++++++++++++++++++++-----
pyanaconda/ui/gui/spokes/welcome.py | 2 +-
3 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/pyanaconda/constants.py b/pyanaconda/constants.py
index ee9ffdb..175dc36 100644
--- a/pyanaconda/constants.py
+++ b/pyanaconda/constants.py
@@ -141,6 +141,9 @@ GEOLOC_GEOCODER_NOMINATIM = "geocoder_nominatim"
# default providers
GEOLOC_DEFAULT_PROVIDER = GEOLOC_PROVIDER_FEDORA_GEOIP
GEOLOC_DEFAULT_GEOCODER = GEOLOC_GEOCODER_NOMINATIM
+# timeout (in seconds)
+GEOLOC_TIMEOUT = 3
+
ANACONDA_ENVIRON = "anaconda"
FIRSTBOOT_ENVIRON = "firstboot"
diff --git a/pyanaconda/geoloc.py b/pyanaconda/geoloc.py
index 5a6da14..bb5619f 100644
--- a/pyanaconda/geoloc.py
+++ b/pyanaconda/geoloc.py
@@ -117,6 +117,11 @@ from pyanaconda import nm
location_info_instance = None
+# when waiting for result from geolocation,
+# how ofthen should we check if a result was returned or
+# if the timetout was reached (in seconds)
+GEOLOC_TIMEOUT_CHECK_INTERVAL = 0.2
+
def init_geolocation(provider_id=constants.GEOLOC_DEFAULT_PROVIDER):
"""Prepare the geolocation module for handling geolocation queries.
@@ -143,7 +148,7 @@ def refresh():
log.debug("Geoloc: refresh() called before init_geolocation()")
-def get_territory_code():
+def get_territory_code(wait=False):
"""This function returns the current country code
or None, if:
- no results were found
@@ -151,16 +156,17 @@ def get_territory_code():
- the geolocation module was not activated (init & refresh were not called)
- this is for example the case during image and directory installs
+ :param wait: wait for wait seconds for lookup in progress to finish
:return: current country code or None if not known
:rtype: string or None
"""
- if location_info_instance:
+ if _get_location_info_instance(wait):
return location_info_instance.get_territory_code()
else:
return None
-def get_timezone():
+def get_timezone(wait=False):
"""This function returns the current time zone
or None, if:
- no timezone was found
@@ -168,28 +174,29 @@ def get_timezone():
- the geolocation module was not activated (init & refresh were not called)
- this is for example the case during image and directory installs
+ :param wait: wait for wait seconds for lookup in progress to finish
:return: current timezone or None if not known
:rtype: string or None
"""
- if location_info_instance:
+ if _get_location_info_instance(wait):
return location_info_instance.get_timezone()
else:
return None
-def get_result():
+def get_result(wait=False):
"""Returns the current geolocation result wrapper
or None, if:
- no results were found
- the refresh is still in progress
- the geolocation module was not activated (init & refresh were not called)
-
- this is for example the case during image and directory installs
+ :param wait: wait for wait seconds for lookup in progress to finish
:return: LocationResult instance or None if location is unknown
:rtype: LocationResult or None
"""
- if location_info_instance:
+ if _get_location_info_instance(wait):
return location_info_instance.get_result()
else:
return None
@@ -236,6 +243,47 @@ def _get_provider(provider_id):
return provider()
+def _get_location_info_instance(wait=False):
+ """Just return instance of the location info object
+ and optionally wait for the Geolocation thread to finish
+
+ Meaning of the wait parameter:
+ - False or <=0: don't wait
+ - True : wait for default number of seconds specified by
+ the GEOLOC_TIMEOUT constant
+ - >0 - wait for a given number of seconds
+ :param wait: specifies if this function should wait
+ for the lookup to finish before returning the instance
+ :type wait: bool or integer
+
+ If there is no lookup in progress (no Geolocation refresh thread
+ is running, this function returns at once).
+ """
+
+ if wait:
+ # check if wait is boolean or a number
+ if wait is True:
+ wait = constants.GEOLOC_TIMEOUT
+ time_elapsed = 0
+ # first check if the geolocation thread is running
+ if threadMgr.get(constants.THREAD_GEOLOCATION_REFRESH):
+ while time_elapsed <= wait:
+ # refresh still in progress
+ if threadMgr.get(constants.THREAD_GEOLOCATION_REFRESH):
+ time.sleep(GEOLOC_TIMEOUT_CHECK_INTERVAL)
+ time_elapsed += GEOLOC_TIMEOUT_CHECK_INTERVAL
+ else:
+ break
+ else: # timed out
+ log.info("Waiting for Geolocation timed out after %d seconds."
+ % wait)
+ # please note that this does not mean that the actual
+ # geolocation lookup was stopped in any way, this will
+ # just unblock the caller after the given wait period
+ # even though the lookup thread is still running
+ return location_info_instance
+
+
class GeolocationError(Exception):
"""Exception class for geolocation related errors"""
pass
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 5c3a47f..fec9b68 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -156,7 +156,7 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
# We can use the territory from geolocation here
# to preselect the translation, when it's available.
- territory = geoloc.get_territory_code()
+ territory = geoloc.get_territory_code(wait=True)
self.language = Language(LOCALE_PREFERENCES, territory=territory)
# check if there is one and only one locale for the territory
--
1.8.1.4
More information about the anaconda-patches
mailing list