def filecache(seconds_of_validity=None, fail_silently=False):
    '''
    filecache is called and the decorator should be returned.
    '''
    def filecache_decorator(function):
        @_functools.wraps(function)
        def function_with_cache(*args, **kwargs):
            try:
                key = _args_key(function, args, kwargs)
                if key in function._db:
                    rv = function._db[key]
                    if seconds_of_validity is None or _time.time() - rv.timesig < seconds_of_validity:
                        return rv.data
            except Exception:
                error_str = _traceback.format_exc()
                _log_error(error_str)
                if not fail_silently:
                    raise
            retval = function(*args, **kwargs)
            try:
                function._db[key] = _retval(_time.time(), retval)
                function._db.sync()
            except Exception:
                error_str = _traceback.format_exc()
                _log_error(error_str)
                if not fail_silently:
                    raise
            return retval
        if not hasattr(function, '_db'):
            cache_name = _get_cache_name(function)
            if cache_name in OPEN_DBS:
                function._db = OPEN_DBS[cache_name]
            else:
                function._db = _shelve.open(cache_name)
                OPEN_DBS[cache_name] = function._db
                atexit.register(function._db.close)
            function_with_cache._db = function._db
        return function_with_cache
    if type(seconds_of_validity) == types.FunctionType:
        func = seconds_of_validity
        seconds_of_validity = None
        return filecache_decorator(func)
    return filecache_decorator