async def METHOD_NAME(*fn_args, **fn_kwargs):
    if METHOD_NAME.closed:
        raise RuntimeError("alru_cache is closed for {}".format(METHOD_NAME))
    loop = asyncio.get_event_loop()
    key = _make_key(fn_args, fn_kwargs, typed)
    fut = METHOD_NAME._cache.get(key)
    if fut is not None:
        if not fut.done():
            _cache_hit(METHOD_NAME, key)
            return await asyncio.shield(fut)
        exc = fut._exception
        if exc is None or cache_exceptions:
            _cache_hit(METHOD_NAME, key)
            return fut.result()
        # exception here and cache_exceptions == False
        METHOD_NAME._cache.pop(key)
    fut = loop.create_future()
    task = loop.create_task(fn(*fn_args, **fn_kwargs))
    task.add_done_callback(partial(_done_callback, fut))
    METHOD_NAME.tasks.add(task)
    task.add_done_callback(METHOD_NAME.tasks.remove)
    METHOD_NAME._cache[key] = fut
    if maxsize is not None and len(METHOD_NAME._cache) > maxsize:
        METHOD_NAME._cache.popitem(last=False)
    _cache_miss(METHOD_NAME, key)
    return await asyncio.shield(fut)