[bmap-tools] [PATCH 3/3] TransRead: improve user experience

Artem Bityutskiy dedekind1 at gmail.com
Fri Sep 13 06:48:14 EDT 2013


From: Artem Bityutskiy <artem.bityutskiy at intel.com>

This patch solves the following problem.

1. I forgot to define the proxy.
2. I run bmaptool, it blocks, and several minutes later it fails with an error
   like "Connection timed out"

I would instead like it to tell me that something is going wrong much earlier,
why should I wait for several minutes?

This patch improves the way we open URLs. Now instead of using the default
(usually long) timeout, we first try with a short timeout, and if we cannot
open the URL, we print user a warning, and then try to open with the default
timeout. The user may press Ctrl-C once he/she sees the warning, or start
checking the connectivity.

Change-Id: Ia5f387de62574d84d914c21794f782b1b41d530f
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
 bmaptools/TransRead.py | 47 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/bmaptools/TransRead.py b/bmaptools/TransRead.py
index 49c7b59..b8ab73b 100644
--- a/bmaptools/TransRead.py
+++ b/bmaptools/TransRead.py
@@ -439,8 +439,17 @@ class TransRead:
         Open an URL 'url' and return the file-like object of the opened URL.
         """
 
+        def _print_warning(logger, timeout):
+            """
+            This is a small helper function for printing a warning if we cannot
+            open the URL for some time.
+            """
+            logger.warning("failed to open the URL with %d sec timeout, is the "
+                           "proxy setup correctly? Keep trying..." % timeout)
+
         import urllib2
         import httplib
+        import socket
 
         parsed_url = urlparse.urlparse(url)
         username = parsed_url.username
@@ -473,15 +482,35 @@ class TransRead:
         opener.addheaders = [('User-Agent', 'Mozilla/5.0')]
         urllib2.install_opener(opener)
 
-        try:
-            f_obj = opener.open(url)
-        except urllib2.URLError as err:
-            raise Error("cannot open URL '%s': %s" % (url, err))
-        except (IOError, ValueError, httplib.InvalidURL) as err:
-            raise Error("cannot open URL '%s': %s" % (url, err))
-        except httplib.BadStatusLine:
-            raise Error("cannot open URL '%s': server responds with an HTTP "
-                        "status code that we don't understand" % url)
+        # Open the URL. First try with a short timeout, and print a message
+        # which should supposedly give the a clue that something may be going
+        # wrong.
+        # The overall purpose of this is to improve user experience. For
+        # example, if one tries to open a file but did not setup the proxy
+        # environment variables propely, there will be a very long delay before
+        # the failure message. And it is much nicer to pre-warn the user early
+        # about something possibly being wrong.
+        for timeout in (10, None):
+            try:
+                f_obj = opener.open(url, timeout = timeout)
+            # Handling the timeout case in Python 2.7
+            except socket.timeout, err:
+                if timeout is not None:
+                    _print_warning(self._logger, timeout)
+                else:
+                    raise Error("cannot open URL '%s': %s" % (url, err))
+            except urllib2.URLError as err:
+                # Handling the timeout case in Python 2.7
+                if timeout is not None and \
+                   isinstance(err.reason, socket.timeout):
+                    _print_warning(self._logger, timeout)
+                else:
+                    raise Error("cannot open URL '%s': %s" % (url, err))
+            except (IOError, ValueError, httplib.InvalidURL) as err:
+                raise Error("cannot open URL '%s': %s" % (url, err))
+            except httplib.BadStatusLine:
+                raise Error("cannot open URL '%s': server responds with an "
+                            "HTTP status code that we don't understand" % url)
 
         self.is_url = True
         self._f_objs.append(f_obj)
-- 
1.8.1.4




More information about the Bmap-tools mailing list