'Decorator for functions supporting a ``channel`` keyword argument.
The resulting callable will retry calling the function if
it raises connection or channel related errors.
The return value will be a tuple of ``(retval, last_created_channel)``.
If a ``channel`` is not provided, then one will be automatically
acquired (remember to close it afterwards).
See Also:
:meth:`ensure` for the full list of supported keyword arguments.
Example:
>>> channel = connection.channel()
>>> try:
...    ret, channel = connection.autoretry(
...         publish_messages, channel)
... finally:
...    channel.close()'

def autoretry(self, fun, channel=None, **ensure_options):

    channels = [channel]
    class Revival(object, ):
        __name__ = getattr(fun, u'__name__', None)
        __module__ = getattr(fun, u'__module__', None)
        __doc__ = getattr(fun, u'__doc__', None)
        def __init__(self, connection):
            self.connection = connection
        def revive(self, channel):
            channels[0] = channel
        def __call__(self, *args, **kwargs):
            if (channels[0] is None):
                self.revive(self.connection.default_channel)
            return (fun(channel=channels[0], *args, **kwargs), channels[0])
    revive = Revival(self)
    return self.ensure(revive, revive, **ensure_options)
