How to safely maintain a status file

Michael Hrivnak mhrivnak at hrivnak.org
Sun Jul 8 12:47:25 EDT 2012


What are you keeping in this status file that needs to be saved
several times per second?  Depending on what type of state you're
storing and how persistent it needs to be, there may be a better way
to store it.

Michael

On Sun, Jul 8, 2012 at 7:53 AM, Christian Heimes <lists at cheimes.de> wrote:
> Am 08.07.2012 13:29, schrieb Richard Baron Penman:
>> My initial solution was a thread that writes status to a tmp file
>> first and then renames:
>>
>> open(tmp_file, 'w').write(status)
>> os.rename(tmp_file, status_file)
>
> You algorithm may not write and flush all data to disk. You need to do
> additional work. You must also store the tmpfile on the same partition
> (better: same directory) as the status file
>
> with open(tmp_file, "w") as f:
>     f.write(status)
>     # flush buffer and write data/metadata to disk
>     f.flush()
>     os.fsync(f.fileno())
>
> # now rename the file
> os.rename(tmp_file, status_file)
>
> # finally flush metadata of directory to disk
> dirfd = os.open(os.path.dirname(status_file), os.O_RDONLY)
> try:
>     os.fsync(dirfd)
> finally:
>     os.close(dirfd)
>
>
>> This works well on Linux but Windows raises an error when status_file
>> already exists.
>> http://docs.python.org/library/os.html#os.rename
>
> Windows doesn't suppport atomic renames if the right side exists.  I
> suggest that you implement two code paths:
>
> if os.name == "posix":
>     rename = os.rename
> else:
>     def rename(a, b):
>         try:
>             os.rename(a, b)
>         except OSError, e:
>             if e.errno != 183:
>                 raise
>             os.unlink(b)
>             os.rename(a, b)
>
> Christian
>
> --
> http://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list