view web/atomicfile.py @ 577:c3bad5ceb560

merge
author Matt Johnston <matt@ucc.asn.au>
date Tue, 17 Nov 2015 22:26:54 +0800
parents 236e5d131b3e
children 87c20b8c5472
line wrap: on
line source

import os
import time
import fcntl
import sys

class AtomicFile(object):
    DELAY = 0.5
    def __init__(self, name):
        self.name = name

    def write(self, data, timeout = 5):
        try:
            end = time.time() + timeout
            with open(self.name, "r+") as f:
                while timeout == 0 or time.time() < end:
                    try:
                        fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
                    except IOError:
                        time.sleep(DELAY)
                        continue

                    os.ftruncate(f.fileno(), 0)
                    f.write(data)
                    return True

        except IOError, e:
            print>>sys.stderr, e

        return False

    def read(self, timeout = 5):
        try:
            end = time.time() + timeout
            with open(self.name, "r") as f:
                while timeout == 0 or time.time() < end:
                    try:
                        fcntl.lockf(f, fcntl.LOCK_SH | fcntl.LOCK_NB)
                    except IOError:
                        time.sleep(DELAY)
                        continue

                    return f.read()

        except IOError, e:
            print>>sys.stderr, e

        return None