0

Hi I have the following issue, I want to execute getlastItemFromGivenInterval method, let it briefly to go through without waiting for request reponses, and give a context to asyncio.sleep(60) to execute the whole procedure once more in 60 seconds time frames. What I get is waiting in getLastItemFromGivenInterval() for request end.

import aiohttp
import asyncio

loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_forever()

async def main():
    async with aiohttp.ClientSession() as session:
        while True:
            await bc.getLastItemFromGivenInterval(session)
            await asyncio.sleep(60)

async def getLastItemFromGivenInterval(session):
    async with session.get(BinanceClient.base_endpoint + "/api/v1/time") as currentServerTime:
        currentServerTime = await currentServerTime.json()
        currentServerTime = currentServerTime['serverTime']

    async with session.get(url) as res:
        response = await res.json()
        array = []
        print(response)

        return response

getLastItemFromGivenInterval is placed in the separate class. Please give me a hint how to achieve not waiting effect in getLastItem...() method.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • I'm not 100% clear on your question, but it seems that your problem is that the `getlastItemFromGivenInterval` and `sleep` are synchronous -- If you want to run them concurrently, then you probably want to await the result of an `asyncio.gather` -- `await asyncio.gather(bc.getLastItemFromGivenInterval(session), asyncio.sleep(60))` rather than awaiting each item individually. – mgilson Dec 30 '18 at 15:38
  • @mgilson I think the OP doesn't want to wait for `getLastItemFromGivenInterval` at all. `gather()` will parallelize the sleep with the coroutine execution, but it can still take arbitrarily long to complete if the coroutine ends up taking a long time, and that's something the OP is working to avoid. – user4815162342 Dec 30 '18 at 22:47
  • How to get the result of the first coroutine in the asyncio.gather() just after it is finished? – Jack Wilkinson Jan 05 '19 at 10:27

1 Answers1

0

If I understand you correctly, you want to start getLastItemFromGivenInterval in the background, and do so every 60 seconds regardless of how long it takes to complete. You can replace await with create_task, and then never awaiting the resulting task:

loop = asyncio.get_event_loop()
while True:
    # spawn the task in the background, and proceed
    loop.create_task(bc.getLastItemFromGivenInterval(session))
    # wait 60 seconds, allowing the above task (and other
    # tasks managed by the event loop) to run
    await asyncio.sleep(60)

You might want to also ensure that tasks that take a long time to complete or that hang indefinitely (e.g. due to a network failure) don't accumulate:

loop = asyncio.get_event_loop()
while True:
    # asyncio.wait_for will cancel the task if it takes longer
    # than the specified duration
    loop.create_task(asyncio.wait_for(
        bc.getLastItemFromGivenInterval(session), 500))
    await asyncio.sleep(60)
user4815162342
  • 141,790
  • 18
  • 296
  • 355