version: apache-libcloud-1.0.0-pre1

libcloud/common/base.py

In earlier versions of Libcloud (0.16 for sure), the only way that I found
to control the connection timeout for the various storage drivers was to
override _ex_connection_class_kwargs() in a subclass of the driver. For
example:

class ExampleMixin:
    def _ex_connection_class_kwargs(self):
        '''
        You are in a maze of twisty little passages, all alike...
        '''
        # This method is the only way to push a timeout value down into the
        # underlying socket connection used by the storage driver.
        #
        # Without this timeout, if the network fails for some reason while
        # we are trying to talk to the cloud, the socket can hang forever.
        kwargs = super()._ex_connection_class_kwargs()
        kwargs['timeout'] = 120

        return kwargs

After we upgraded to 1.0.0-pre1, our connection timeout stopped working.
Looking in BaseDriver.__init__(), you can see why it doesn't work anymore.

*Previously (0.16):*

class BaseDriver(object):
    """
    Base driver class from which other classes can inherit from.
    """

    connectionCls = ConnectionKey

    def __init__(self, key, secret=None, secure=True, host=None, port=None,
                 api_version=None, region=None, **kwargs):

        # snip code that isn't relevant

        conn_kwargs = self._ex_connection_class_kwargs()
        self.connection = self.connectionCls(*args, **conn_kwargs)
        ...

*Now (1.0.0-pre1):*

class BaseDriver(object):
    """
    Base driver class from which other classes can inherit from.
    """

    connectionCls = ConnectionKey

    def __init__(self, key, secret=None, secure=True, host=None, port=None,
                 api_version=None, region=None, **kwargs):

        # snip

        conn_kwargs = self._ex_connection_class_kwargs()
        conn_kwargs.update({'timeout': kwargs.pop('timeout', None),
                            'retry_delay': kwargs.pop('retry_delay', None),
                            'backoff': kwargs.pop('backoff', None),
                            'proxy_url': kwargs.pop('proxy_url', None)})
        self.connection = self.connectionCls(*args, **conn_kwargs)
        ...

Not sure if this is just a bug or a change in the design, but it breaks
existing code.

I did a minimal patch to my repo to fix the timeout stomp, but presumably
it's wrong to have the other parameters like this as well. Here's my patch:

diff -r 5d23cd267cdc libcloud/common/base.py
--- a/libcloud/common/base.py Mon Apr 11 22:08:14 2016 +0000
+++ b/libcloud/common/base.py Thu Apr 14 21:03:16 2016 +0000
@@ -1155,8 +1155,12 @@
         self.verify_ssl_cert = kwargs.get('verify_ssl_cert', None)

         conn_kwargs = self._ex_connection_class_kwargs()
-        conn_kwargs.update({'timeout': kwargs.pop('timeout', None),
-                            'retry_delay': kwargs.pop('retry_delay', None),
+        # iio: Libcloud was stomping on the connection timeout set in
+        # _ex_connection_class_kwargs()
+        timeout = kwargs.pop('timeout', None)
+        if conn_kwargs.get('timeout', None) is None:
+            conn_kwargs['timeout'] = timeout
+        conn_kwargs.update({'retry_delay': kwargs.pop('retry_delay', None),
                             'backoff': kwargs.pop('backoff', None),
                             'proxy_url': kwargs.pop('proxy_url', None)})
         self.connection = self.connectionCls(*args, **conn_kwargs)

Thanks,
Jay

Reply via email to