Open emile-cronje opened 8 months ago
Apologies for the messy code part of this issue, pasting the code did not work as expected, I have attached the script.
Regards producer_consumer_sd.zip
Found the following with AddressSanitizer in VS 2022
@emile-cronje μSQLite has been updated to v0.1.5 which includes the latest version of SQLite and support for MicroPython v1.23. This may address some of the problems you've encountered.
Please also take a look at the simple memory test shown in https://github.com/spatialdude/usqlite/issues/27#issuecomment-2143392882 that shows how to trace calls and track peak memory usage that may also assist in narrowing down problems.
Good day
If I run the attached script (see below), tested on windows, unix and stm32f769 builds, it runs fine until the free memory drops below 5%, and then crashes with the error:
Traceback (most recent call last): File "E:\scratch\micropython\mp_usqlite\samples\producer_consumer_sd.py", line 167, in
File "asyncio/core.py", line 1, in run
File "asyncio/core.py", line 1, in run_until_complete
File "E:\scratch\micropython\mp_usqlite\samples\producer_consumer_sd.py", line 91, in consume
usqlite_Error: error (26): file is not a database sql: 'SELECT COUNT(ID) from items;'
PS E:\scratch\micropython\mp_usqlite\micropython\ports\windows\build-dev>
If I run the script with useSqlite = False, the memory usage drops until about 1%, but the the gc kicks in and continues as expected.
Although, if useSqlite = True, when the memory usage drops to around 5%, the above error is displayed. Might it be an issue in the interop between the gc and usqlite?
Regards
Script:
import uasyncio as asyncio from queue import Queue import gc import os import usqlite
Exception raised by get_nowait().
class QueueEmpty(Exception): pass
Exception raised by put_nowait().
class QueueFull(Exception): pass
class Queue: def init(self, maxsize=0): self.maxsize = maxsize self._queue = [] self._evput = asyncio.Event() # Triggered by put, tested by get self._evget = asyncio.Event() # Triggered by get, tested by put
event_test = asyncio.Event() useSqlite = False
async def produce(queue): icount = 0
async def consume(queue, dbConn): while True: await event_test.wait()
print("Pulled item..." + str(item))
async def watchQueue(queue): while True: if (queue.qsize() > 10): event_test.set()
async def showQueueLength(queue): while True: print("Queue length..." + str(queue.qsize())) await asyncio.sleep(2)
async def showMemUsage(): while True: print(free(True)) await asyncio.sleep(5)
def free(full=False): F = gc.mem_free() A = gc.mem_alloc() T = F+A P = '{0:.2f}%'.format(F/T*100) if not full: return P else : return ('Total:{0} Free:{1} ({2})'.format(T,F,P))
def InitDb(clearDb = True): dbconn = usqlite.connect("data.db")
os.rmdir('sd')
os.mkdir('sd')
os.remove("data.db")
async def main(): queue = Queue()
dbConn = InitDb() asyncio.create_task(produce(queue))
asyncio.create_task(consume(queue, dbConn))
asyncio.create_task(watchQueue(queue))
asyncio.create_task(showQueueLength(queue)) asyncio.create_task(showMemUsage())
asyncio.run(main())