annotate web/atomicfile.py @ 196:e27075b1e088

Make sure we close descriptor before rename
author Matt Johnston <matt@ucc.asn.au>
date Wed, 12 Feb 2014 20:57:30 +0800
parents 8318d50d766d
children 6dd157a12035
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
191
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 import os
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 import time
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 import fcntl
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 import sys
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 class AtomicFile(object):
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 DELAY = 0.5
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 def __init__(self, name):
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 self.name = name
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 def write(self, data, timeout = 5):
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 try:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 end = time.time() + timeout
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 with open(self.name, "r+") as f:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 while timeout == 0 or time.time() < end:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 try:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 except IOError:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 time.sleep(DELAY)
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 continue
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 f.write(data)
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 return True
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 except IOError, e:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 print>>sys.stderr, e
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 return False
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 def read(self, timeout = 5):
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 try:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 end = time.time() + timeout
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 with open(self.name, "r") as f:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 while timeout == 0 or time.time() < end:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 try:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 fcntl.lockf(f, fcntl.LOCK_SH | fcntl.LOCK_NB)
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 except IOError:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 time.sleep(DELAY)
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 continue
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 return f.read()
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43 except IOError, e:
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 print>>sys.stderr, e
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45
8318d50d766d gets current params
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 return None