comparison env/lib/python3.7/site-packages/lockfile/sqlitelockfile.py @ 5:9b1c78e6ba9c draft default tip

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