Are file writes non blocking?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
KJM
Posts: 158
Joined: Sun Nov 18, 2018 10:53 pm
Location: Sydney AU

Are file writes non blocking?

Post by KJM » Wed Jan 19, 2022 11:01 am

I've got a problem with

Code: Select all

with open('update', 'w') as f: f.write(update); print('update stored'); machine.deepsleep(900*1000)
Where update is a 29k text file. The problem is the update file is created in flash but has nothing in it. I don't understand how the print can output if the write hasn't happened?

I tried allowing some extra time for the write to occur with

Code: Select all

with open('update', 'w') as f: f.write(update); time.sleep(1); print('update stored'); machine.deepsleep(900*1000)
but same result, the appearance of a zero size update file in os.listdir() after the program has run.

If I move the write a few lines further up before the deeplseep it works properly but I don't understand why. Can anyone suggest what's going on?

User avatar
scruss
Posts: 360
Joined: Sat Aug 12, 2017 2:27 pm
Location: Toronto, Canada
Contact:

Re: Are file writes non blocking?

Post by scruss » Wed Jan 19, 2022 4:28 pm

write needs a flush or the passage of time to make them happen

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Are file writes non blocking?

Post by Roberthh » Wed Jan 19, 2022 5:05 pm

Try to write the code a little bit different.

Code: Select all

with open('update', 'w') as f:
    f.write(update);
print('update stored');
machine.deepsleep(900*1000)
As far as In understand, everything behind the : after with or if or ... is considered as a single statement. And since that includes deepsleep(), the automatic flush() after the with statement does not happen.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Are file writes non blocking?

Post by davef » Wed Jan 19, 2022 6:25 pm

Even a print() statement before lightsleep() or deepsleep() needs a wait or you only get part of it.

Code: Select all

    print ('going to lightsleep() for the timer duration')
    utime.sleep(.5) #  so print() works
    machine.lightsleep(5 * 1000)

KJM
Posts: 158
Joined: Sun Nov 18, 2018 10:53 pm
Location: Sydney AU

Re: Are file writes non blocking?

Post by KJM » Wed Jan 19, 2022 10:35 pm

Looks like I'm a victim of my penchant for multi cmd lines! If I limit myself to 1 cmd per line I end up doing a LOT of scrolling due code dev. Is there a way around this or do I need to get a bigger monitor & set it up in portrait mode?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Are file writes non blocking?

Post by dhylands » Wed Jan 19, 2022 11:29 pm

How are you checking the file size?

I don't think that closing the file means that it's written to the filesystem by the time that the close returns.

I think you would need to call os.sync() to ensure that everything has actually been committed to flash. deepsleep is like a reset, so if the data was sitting in memory in a cache, it's gone by the time deepsleep returns since deepsleep is like a reset.

KJM
Posts: 158
Joined: Sun Nov 18, 2018 10:53 pm
Location: Sydney AU

Re: Are file writes non blocking?

Post by KJM » Fri Jan 21, 2022 12:26 am

I gave that a try in an attempt to force a flush

Code: Select all

with open('update', 'w') as f: f.write(update)                                                                                                      
os.sync()
but I must be doing it wrong?

Code: Select all

line 101 AttributeError: module object has no attribute sync

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Are file writes non blocking?

Post by Roberthh » Fri Jan 21, 2022 10:11 am

you can use f.flush(), or simply leave the with() code block after with. That will close the file, and on file close the buffer will be flushed as well. So if you write your code in proper style, everything should go well.

Code: Select all

with open('update', 'w') as f:
	f.write(update)                                                                                                      
You problem is, that the deepsleep() call is on the same code line as the with(). Then, the with code block was not left before deepsleep, and the intrinsic flush and close did not happen.
Edit: The ';' in a statement list binds stronger than the colon ':'. So the statement list after 'with' is treated as a single statement.

Post Reply