uasyncio --- Cleaning up after a task

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.
Post Reply
doceave
Posts: 26
Joined: Fri Feb 14, 2020 4:02 pm

uasyncio --- Cleaning up after a task

Post by doceave » Sat Apr 04, 2020 7:06 pm

Hi there everyone

It is very likely that owing to my poor implementation of the uasyncio library, on an ESP32 WROOM32, that after a few minutes of running memory intensive tasks, bugs begin revealing themselves. All functions test well initially, but after a while seemingly random error is raised in the REPL:

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ACT_v0b.py", line 1154, in <module>
  File "uasyncio/core.py", line 109, in run_forever
  File "ACT_v0b.py", line 1070, in ACT_Now_R
  File "uasyncio/core.py", line 180, in run_until_complete
  File "uasyncio/core.py", line 92, in run_forever
IndexError: empty
>>>
My gut tells me that I am not cleaning up well after running certain functions repeatedly with resultant memory issues that develop in a use-time dependent manner...

Put simply, is there a proper way to clean up after functions that are called using "create_task", which return immediately but may be called multiple times from different places? Example:

Code: Select all

loop = asyncio.get_event_loop()
loop.run_until_complete(json_get_settings())
loop.run_until_complete(wifi_connect())
loop.create_task(home_screen())
Or anything else which could explain odd behavior as a function of time/usage?

Thanks.

kevinkk525
Posts: 774
Joined: Sat Feb 03, 2018 7:02 pm

Re: uasyncio --- Cleaning up after a task

Post by kevinkk525 » Sat Apr 04, 2020 7:39 pm

I have a few questions:

1. Are you using the new uasyncio that got merged within the last weeks (and is present in daily builds) or the old one? (If you have asyncio.run then it is the new one)
2. Why are you calling loop.run_until_complete multiple times? Typically you're program should have one main loop that is always running and then create tasks.
3. You clean up the RAM by calling gc.collect(). Although that will happen automatically eventually, when the available RAM gets too low, but RAM fragmentation can cause problems and at some point there might not be enough contiguous RAM available. Try getting some output from gc.mem_free() and micropython.mem_info(1) when it crashes.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

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

Re: uasyncio --- Cleaning up after a task

Post by pythoncoder » Sun Apr 05, 2020 6:42 am

You can test for the new version with

Code: Select all

import uasyncio as asyncio
asyncio.__version__
The old version will throw an exception, the new one will issue (3, 0, 0).

@doceave As Kevin says you are using uasyncio in a strange way. I suggest you look at the tutorial in this repo.
Peter Hinch

doceave
Posts: 26
Joined: Fri Feb 14, 2020 4:02 pm

Re: uasyncio --- Cleaning up after a task

Post by doceave » Sun Apr 05, 2020 11:12 am

I am indeed using the older version of uasyncio
> Upgrade pending

Following numerous reviews of the linked tutorial I now finally get it!
> I now have a main loop which starts tasks, each of which await coros as needed :)

As always... many many thanks for the gentle assistance.

Post Reply