<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def construct_time_based_cache_middleware( cache_class, cache_expire_seconds=15, rpc_whitelist=TIME_BASED_CACHE_RPC_WHITELIST, should_cache_fn=_should_cache):
 """ Constructs a middleware which caches responses based on the request ``method`` and ``params`` for a maximum amount of time as specified :param cache: Any dictionary-like object :param cache_expire_seconds: The number of seconds an item may be cached before it should expire. :param rpc_whitelist: A set of RPC methods which may have their responses cached. :param should_cache_fn: A callable which accepts ``method`` ``params`` and ``response`` and returns a boolean as to whether the response should be cached. """

    def time_based_cache_middleware(make_request, web3):
        cache = cache_class()
        lock = threading.Lock()

        def middleware(method, params):
            lock_acquired = lock.acquire(blocking=False)

            try:
                if lock_acquired and method in rpc_whitelist:
                    cache_key = generate_cache_key((method, params))
                    if cache_key in cache:
                        # check that the cached response is not expired.
                        cached_at, cached_response = cache[cache_key]
                        cached_for = time.time() - cached_at

                        if cached_for <= cache_expire_seconds:
                            return cached_response
                        else:
                            del cache[cache_key]

                    # cache either missed or expired so make the request.
                    response = make_request(method, params)

                    if should_cache_fn(method, params, response):
                        cache[cache_key] = (time.time(), response)

                    return response
                else:
                    return make_request(method, params)
            finally:
                if lock_acquired:
                    lock.release()
        return middleware
    return time_based_cache_middleware