Home > Software design >  asyncio: pass object trough loops and threads python
asyncio: pass object trough loops and threads python

Time:11-06

i'm just learning asyncio and threads, so if someting is wrong, sorry

this is my code:

async def callback_onlyAlert(update: Update, context):
    await update.message.reply_text('Ok! \nI will send you a message only when you can withdraw your USDN')
    #run alert 
    t = threading.Thread(target=middleware_alert, args=(update, context,))
    t.start()


def middleware_alert(update: Update,context):
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(alert(update, context))
    loop.close()


async def alert(update: Update, context):
     global block
     global withdrawal_block
     while True:
        await  update.message.reply_text("⚠️⚠️ -10 MINUTES! ⚠️⚠️")
        time.sleep(20)

when i run it, i get got Future <Future pending> attached to a different loop error, i know that asyncio make a loop for the main thread, and you can't pass object trough loops, so i think that's why i get this error

anyway i get update and context outside that loop, when app starts, so i can't create it after the loop starts, there is any turnaround? or i'm doing something wrong? thanks

CodePudding user response:

Passing objects through loops and threads

Both thread and async functions share objects if you use Lock properly.

I am not sure about the rest part of your code, but it seems you're trying to have a loop per thread which is not possible. But if you really was trying to have multiple event loops for some reason, you should invoke asyncio.new_event_loop in a separate process.

NOTE: Using processes, you will lose the object-sharing ability. Sure it allows provide prime type objects such as str, int, etc. between processes but it makes some difficulties for complex objects. If you are interested in that topic, I suggest you to read this.

CodePudding user response:

If all you're trying to do is launch the alert coroutine so that it runs at the same time as the rest of your code (without waiting for it to finish), I believe the asyncio-ish way to do that would be:

async def callback_onlyAlert(update: Update, context):
    await update.message.reply_text('Ok! \nI will send you a message only when you can withdraw your USDN')
    #run alert 
    asyncio.create_task(alert(update, context))

You shouldn't be running multiple event loops in different threads for this. Also, you should use await asyncio.sleep(10) instead of time.sleep(10), otherwise the entire event loop gets blocked.

  • Related