annotate lockfile-0.10.2/lockfile/sqlitelockfile.py @ 47:b19e848f9886

update xena to v16
author jingchunzhu
date Fri, 07 Aug 2015 17:01:10 -0700
parents 7ceb967147c3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
1 from __future__ import absolute_import, division
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
2
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
3 import time
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
4 import os
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
5
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
6 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
7 unicode
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
8 except NameError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
9 unicode = str
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
10
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
11 from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
12
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
13 class SQLiteLockFile(LockBase):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
14 "Demonstrate SQL-based locking."
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
15
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
16 testdb = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
17
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
18 def __init__(self, path, threaded=True, timeout=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
19 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
20 >>> lock = SQLiteLockFile('somefile')
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
21 >>> lock = SQLiteLockFile('somefile', threaded=False)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
22 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
23 LockBase.__init__(self, path, threaded, timeout)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
24 self.lock_file = unicode(self.lock_file)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
25 self.unique_name = unicode(self.unique_name)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
26
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
27 if SQLiteLockFile.testdb is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
28 import tempfile
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
29 _fd, testdb = tempfile.mkstemp()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
30 os.close(_fd)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
31 os.unlink(testdb)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
32 del _fd, tempfile
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
33 SQLiteLockFile.testdb = testdb
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
34
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
35 import sqlite3
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
36 self.connection = sqlite3.connect(SQLiteLockFile.testdb)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
37
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
38 c = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
39 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
40 c.execute("create table locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
41 "("
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
42 " lock_file varchar(32),"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
43 " unique_name varchar(32)"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
44 ")")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
45 except sqlite3.OperationalError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
46 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
47 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
48 self.connection.commit()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
49 import atexit
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
50 atexit.register(os.unlink, SQLiteLockFile.testdb)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
51
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
52 def acquire(self, timeout=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
53 timeout = timeout is not None and timeout or self.timeout
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
54 end_time = time.time()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
55 if timeout is not None and timeout > 0:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
56 end_time += timeout
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
57
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
58 if timeout is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
59 wait = 0.1
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
60 elif timeout <= 0:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
61 wait = 0
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
62 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
63 wait = timeout / 10
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
64
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
65 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
66
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
67 while True:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
68 if not self.is_locked():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
69 # Not locked. Try to lock it.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
70 cursor.execute("insert into locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
71 " (lock_file, unique_name)"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
72 " values"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
73 " (?, ?)",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
74 (self.lock_file, self.unique_name))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
75 self.connection.commit()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
76
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
77 # Check to see if we are the only lock holder.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
78 cursor.execute("select * from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
79 " where unique_name = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
80 (self.unique_name,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
81 rows = cursor.fetchall()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
82 if len(rows) > 1:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
83 # Nope. Someone else got there. Remove our lock.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
84 cursor.execute("delete from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
85 " where unique_name = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
86 (self.unique_name,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
87 self.connection.commit()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
88 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
89 # Yup. We're done, so go home.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
90 return
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
91 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
92 # Check to see if we are the only lock holder.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
93 cursor.execute("select * from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
94 " where unique_name = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
95 (self.unique_name,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
96 rows = cursor.fetchall()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
97 if len(rows) == 1:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
98 # We're the locker, so go home.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
99 return
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
100
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
101 # Maybe we should wait a bit longer.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
102 if timeout is not None and time.time() > end_time:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
103 if timeout > 0:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
104 # No more waiting.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
105 raise LockTimeout("Timeout waiting to acquire"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
106 " lock for %s" %
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
107 self.path)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
108 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
109 # Someone else has the lock and we are impatient..
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
110 raise AlreadyLocked("%s is already locked" % self.path)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
111
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
112 # Well, okay. We'll give it a bit longer.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
113 time.sleep(wait)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
114
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
115 def release(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
116 if not self.is_locked():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
117 raise NotLocked("%s is not locked" % self.path)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
118 if not self.i_am_locking():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
119 raise NotMyLock("%s is locked, but not by me (by %s)" %
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
120 (self.unique_name, self._who_is_locking()))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
121 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
122 cursor.execute("delete from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
123 " where unique_name = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
124 (self.unique_name,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
125 self.connection.commit()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
126
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
127 def _who_is_locking(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
128 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
129 cursor.execute("select unique_name from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
130 " where lock_file = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
131 (self.lock_file,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
132 return cursor.fetchone()[0]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
133
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
134 def is_locked(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
135 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
136 cursor.execute("select * from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
137 " where lock_file = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
138 (self.lock_file,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
139 rows = cursor.fetchall()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
140 return not not rows
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
141
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
142 def i_am_locking(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
143 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
144 cursor.execute("select * from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
145 " where lock_file = ?"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
146 " and unique_name = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
147 (self.lock_file, self.unique_name))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
148 return not not cursor.fetchall()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
149
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
150 def break_lock(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
151 cursor = self.connection.cursor()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
152 cursor.execute("delete from locks"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
153 " where lock_file = ?",
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
154 (self.lock_file,))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
155 self.connection.commit()