async def METHOD_NAME():
    return_values = iter(range(10))
    event = asyncio.Event()
    condition = asyncio.Condition()
    num_waiting_coroutines = DataHolder(value=0)
    # Wait until we have enough coroutines waiting to return a result.  This
    # ensures that dependent coroutines have a chance to get a future out of
    # the cache
    @async_ttl_cache(ttl=0)
    async def range_coroutine():
        await event.wait()
        return next(return_values)
    # Wait until we have enough coroutines waiting on range_coroutine, then
    # wake range_coroutine
    async def event_setter():
        async with condition:
            while num_waiting_coroutines.value != 2:
                await condition.wait()
            event.set()
    # Keep track of how many waiting range_coroutines we have to ensure both
    # have had a chance to get the in-flight future out of the cache.  This has
    # to be separate from range_coroutine since we only end up with one
    # invocation of that method due to caching.  It also has to be separate
    # from event_setter to ensure that the event is not set until both
    # coroutines are waiting.
    async def cache_waiter():
        async with condition:
            num_waiting_coroutines.value += 1
            condition.notify_all()
        return await range_coroutine()
    event_setter_future = asyncio.ensure_future(event_setter())
    future1 = asyncio.ensure_future(cache_waiter())
    future2 = asyncio.ensure_future(cache_waiter())
    await asyncio.wait([event_setter_future, future1, future2])
    assert future1.result() == future2.result() == 0