uasyncio, loop doesn't stops

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
jpbihin
Posts: 7
Joined: Thu Feb 08, 2018 5:31 pm
Location: Belgium

uasyncio, loop doesn't stops

Post by jpbihin » Sun Oct 04, 2020 10:58 am

Hi,
Sorry for this beginner's question...
I work with a ESP32-WROOM
This is the code reduced to its simplest version :

Code: Select all

# test asyncio threads
import time
import machine
import sys
from machine import I2C, Pin, Timer, Pin, ADC
import micropython
import uasyncio as asyncio

async def fn_1() :
    while True :
        print("fn_1") 
        print(time.time())
        await asyncio.sleep(4)

loop = asyncio.get_event_loop()
loop.create_task(fn_1())

try :
    loop.run_forever()

except KeyboardInterrupt :
    loop.close()
    print("keyboard interrupt")
    sys.exit()
    
except Exception as e:
    print(e)
    loop.close()
    sys.exit()
The issue: when I run the program once , the result is :

fn_1
41
fn_1
45
fn_1
49
fn_1
53
keyboard interrupt
>>>


next time :

fn_1
152
fn_1
152
fn_1
156
fn_1
156
keyboard interrupt
>>>


etc

...as if the loop continues to run in the background, without stopping...
What is missing in my code to completely stop loops ??

Thanks !
JP

kr-g
Posts: 48
Joined: Sun Dec 01, 2019 7:52 pm
Contact:

Re: uasyncio, loop doesn't stops

Post by kr-g » Mon Oct 05, 2020 6:40 am

with MicroPython v1.13 this works. which version are you using?

or probably related to the overall internal state (when using with REPL)?
how is your development process here?
are you executing the code directly again, and again from an IDE, or do you restart always with cntrl+d ?
in case of IDE re-run you might run into following...

e.g. doubled, or tripled output output

keyboard interrupt
(run again from IDE)

fn_1
14
fn_1
14
fn_1
18
fn_1
18
fn_1
22
fn_1
22

keyboard interrupt
(run again from IDE)

fn_1
27
fn_1
27
fn_1
27
fn_1
31
fn_1
31
fn_1
31
fn_1
35
fn_1
35
fn_1
35
fn_1
39
fn_1
39
fn_1
39

...

anyway. when restructure the code inside another function the cleanup is done properly.
i also moved some of the logic to the finally suite

---

Code: Select all


async def fn_1() :
    while True :
        print("fn_1") 
        print(time.time())
        await asyncio.sleep(4)

def mainloop():

    loop = asyncio.get_event_loop()

    loop.create_task(fn_1())

    try :
        loop.run_forever()

    except KeyboardInterrupt :
        print("keyboard interrupt")
        
    except Exception as e:
        print(e)
    
    finally:
        loop.close()
        #sys.exit()
        

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: uasyncio, loop doesn't stops

Post by pythoncoder » Mon Oct 05, 2020 7:29 am

The preferred way to do this in uasyncio V3 is as follows:

Code: Select all

import time
import uasyncio as asyncio
async def fn_1() :
    while True :
        print("fn_1") 
        print(time.time())
        await asyncio.sleep(4)

asyncio.run(fn_1())
There are things you can do to improve error handling and to stop uasyncio from retaining state. Please see my tutorial for details.

The issue of retaining state means that you have to press ctrl-d between runs. To fix this you need to do

Code: Select all

import time
import uasyncio as asyncio
async def fn_1() :
    while True :
        print("fn_1") 
        print(time.time())
        await asyncio.sleep(4)

try:
    asyncio.run(fn_1())
finally:
    asyncio.new_event_loop()  # Clear retained state
Peter Hinch
Index to my micropython libraries.

kr-g
Posts: 48
Joined: Sun Dec 01, 2019 7:52 pm
Contact:

Re: uasyncio, loop doesn't stops

Post by kr-g » Mon Oct 05, 2020 9:39 am

pythoncoder wrote:
Mon Oct 05, 2020 7:29 am
... The issue of retaining state means that you have to press ctrl-d between runs. To fix this you need to do ...
after reading your reply, and the all code from us - i want to raise one question.

is there are know issue with eventloop.close() ?

in addition i think that there is some more code executed when this gets garbage collected.
from the docu i know that behaviour is bit different ... (also because there is no set_event_loop() method )

Code: Select all


uasyncio.new_event_loop()

    Reset the event loop and return it.

    Note: since MicroPython only has a single event loop this function just resets the loop’s state, it does not create a new one.
that would explain the behaviour that it works as expected when wrapped into a function.
(at least on my board its like that...)

bottom line (as first guess) : does is makes sense to change the current implementation so that close and new_event_loop do the same ?!

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: uasyncio, loop doesn't stops

Post by pythoncoder » Mon Oct 05, 2020 3:28 pm

This is the close() implementation.

A prime purpose of @Damien's rewrite of uasyncio is compatibility with CPython asyncio. I think you'll find that new_event_loop is the asyncio way of doing things.
Peter Hinch
Index to my micropython libraries.

kr-g
Posts: 48
Joined: Sun Dec 01, 2019 7:52 pm
Contact:

Re: uasyncio, loop doesn't stops

Post by kr-g » Mon Oct 05, 2020 4:04 pm

ok - close does nothing than "pass"

CPython (latest)
https://docs.python.org/3/library/async ... loop.close
Last edited by kr-g on Tue Oct 06, 2020 5:58 am, edited 1 time in total.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: uasyncio, loop doesn't stops

Post by pythoncoder » Tue Oct 06, 2020 5:11 am

So uasyncio includes it for compatibility only. The aim is to make it easy to write code which is portable between uasyncio and asyncio. In my experience, so long as you don't use the millisecond level enhancements of uasyncio, this is generally easy. Likewise porting code from asyncio to uasyncio is easy so long as the unsupported features of asyncio are not used (futures, multiple event loops etc). Inevitably uasyncio is largely a "micro" subset of a very complex library.

[EDIT]
I see you've opened an issue on this. I'll be interested to see the maintainers' point of view on this. I'm unconvinced, but they are the experts ;)
Peter Hinch
Index to my micropython libraries.

kr-g
Posts: 48
Joined: Sun Dec 01, 2019 7:52 pm
Contact:

Re: uasyncio, loop doesn't stops

Post by kr-g » Tue Oct 06, 2020 2:08 pm

funny you. i see you here all around with asyncio - and therefore i raised that here to get your opinion onto this...

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: uasyncio, loop doesn't stops

Post by pythoncoder » Tue Oct 06, 2020 4:38 pm

I have long experience of using (and writing) cooperative schedulers and have acquired some knowledge of usayncio. My limited experience of CPython's asyncio has consisted of writing code compatible with both. I can't claim deep knowledge of asyncio and your knowledge of it probably exceeds my own.

I don't especially like the new_event_loop() syntax as, in other respects, V3 code has ditched the concept of an explicit event loop. I agree that close() is more intuitive.

But the bottom line in terms of acceptance is CPython compatibility, not my hand-waving opinions about pretty syntax. If you can produce a script which works under CPython but fails under MP then you should be home and dry. I'm unable to offer a definitive answer.
Peter Hinch
Index to my micropython libraries.

jpbihin
Posts: 7
Joined: Thu Feb 08, 2018 5:31 pm
Location: Belgium

Re: uasyncio, loop doesn't stops

Post by jpbihin » Mon Oct 12, 2020 2:50 pm

Thank you both for your answers ! I will work on my code soon and come back if necessary.
Regardsn
JP

Post Reply