<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def cache_async(self, key_fn=_key_fn, timeout=3600):
 """ Decorator that will execute the cached function in a separate thread. The function will immediately return, returning a callable to the user. This callable can be used to check for a return value. For details, see the :ref:`cache-async` section of the docs. :param key_fn: Function used to generate cache key. :param int timeout: Cache timeout in seconds. :returns: A new function which can be called to retrieve the return value of the decorated function. """

        def decorator(fn):
            wrapped = self.cached(key_fn, timeout)(fn)

            @wraps(fn)
            def inner(*args, **kwargs):
                q = Queue()
                def _sub_fn():
                    q.put(wrapped(*args, **kwargs))
                def _get_value(block=True, timeout=None):
                    if not hasattr(_get_value, '_return_value'):
                        result = q.get(block=block, timeout=timeout)
                        _get_value._return_value = result
                    return _get_value._return_value

                thread = threading.Thread(target=_sub_fn)
                thread.start()
                return _get_value
            return inner
        return decorator