Commit aae9e0dc authored by Michal Čihař's avatar Michal Čihař

Use lockfile module instead of own code.

parent 439551af
...@@ -26,6 +26,8 @@ PIL or Pillow library ...@@ -26,6 +26,8 @@ PIL or Pillow library
http://python-imaging.github.io/ http://python-imaging.github.io/
lxml (>= 3.1.0) lxml (>= 3.1.0)
http://lxml.de/ http://lxml.de/
lockfile
https://pypi.python.org/pypi/lockfile
south south
http://south.aeracode.org/ http://south.aeracode.org/
libravatar (optional for federated avatar support) libravatar (optional for federated avatar support)
......
...@@ -13,6 +13,7 @@ Released on ? 2014. ...@@ -13,6 +13,7 @@ Released on ? 2014.
* Users can now delete their account. * Users can now delete their account.
* Avatars can be disabled. * Avatars can be disabled.
* Merged first and last name attributes. * Merged first and last name attributes.
* Use lockfile module instead of own code.
weblate 1.8 weblate 1.8
----------- -----------
......
...@@ -6,3 +6,4 @@ Translate-Toolkit>=1.10.0 ...@@ -6,3 +6,4 @@ Translate-Toolkit>=1.10.0
lxml>=3.1.0 lxml>=3.1.0
Pillow Pillow
python-social-auth>=0.1.17 python-social-auth>=0.1.17
lockfile>=0.8
# Written by Evan Fosmark
# see http://www.evanfosmark.com/
# Released under BSD license
import os
import time
import errno
class FileLockException(Exception):
pass
class FileLock(object):
"""
A file locking mechanism that has context-manager support so
you can use it in a with statement. This should be relatively cross
compatible as it doesn't rely on msvcrt or fcntl for the locking.
"""
def __init__(self, file_name, timeout=10, delay=.05):
"""
Prepare the file locker. Specify the file to lock and optionally
the maximum timeout and the delay between each attempt to lock.
"""
self.is_locked = False
self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name)
self.file_name = file_name
self.timeout = timeout
self.delay = delay
self.handle = None
def acquire(self):
"""
Acquire the lock, if possible. If the lock is in use, it check again
every `wait` seconds. It does this until it either gets the lock or
exceeds `timeout` number of seconds, in which case it throws
an exception.
"""
start_time = time.time()
while True:
try:
self.handle = os.open(
self.lockfile,
os.O_CREAT | os.O_EXCL | os.O_RDWR
)
break
except OSError as e:
if e.errno != errno.EEXIST:
raise
if (time.time() - start_time) >= self.timeout:
raise FileLockException("Timeout occured.")
time.sleep(self.delay)
self.is_locked = True
def release(self):
"""
Get rid of the lock by deleting the lockfile.
When working in a `with` statement, this gets automatically
called at the end.
"""
if self.is_locked:
os.close(self.handle)
os.unlink(self.lockfile)
self.is_locked = False
def __enter__(self):
"""
Activated when used in the with statement.
Should automatically acquire a lock to be used in the with block.
"""
if not self.is_locked:
self.acquire()
return self
def __exit__(self, typ, value, traceback):
"""
Activated at the end of the with statement.
It automatically releases the lock if it isn't locked.
"""
if self.is_locked:
self.release()
def __del__(self):
"""
Make sure that the FileLock instance doesn't leave a lockfile
lying around.
"""
self.release()
...@@ -32,7 +32,7 @@ import git ...@@ -32,7 +32,7 @@ import git
from weblate.trans.formats import FILE_FORMAT_CHOICES, FILE_FORMATS from weblate.trans.formats import FILE_FORMAT_CHOICES, FILE_FORMATS
from weblate.trans.models.project import Project from weblate.trans.models.project import Project
from weblate.trans.mixins import PercentMixin, URLMixin, PathMixin from weblate.trans.mixins import PercentMixin, URLMixin, PathMixin
from weblate.trans.filelock import FileLock from lockfile import FileLock
from weblate.trans.util import is_repo_link from weblate.trans.util import is_repo_link
from weblate.trans.util import get_site_url from weblate.trans.util import get_site_url
from weblate.trans.util import sleep_while_git_locked from weblate.trans.util import sleep_while_git_locked
......
...@@ -31,7 +31,7 @@ from weblate.trans.models.translation import Translation ...@@ -31,7 +31,7 @@ from weblate.trans.models.translation import Translation
from weblate.trans.models.source import Source from weblate.trans.models.source import Source
from weblate.trans.search import update_index_unit, fulltext_search, more_like from weblate.trans.search import update_index_unit, fulltext_search, more_like
from weblate.trans.filelock import FileLockException from lockfile import LockError
from weblate.trans.util import is_plural, split_plural, join_plural from weblate.trans.util import is_plural, split_plural, join_plural
import weblate import weblate
...@@ -521,7 +521,7 @@ class Unit(models.Model): ...@@ -521,7 +521,7 @@ class Unit(models.Model):
# Store to backend # Store to backend
try: try:
(saved, pounit) = self.translation.update_unit(self, request, user) (saved, pounit) = self.translation.update_unit(self, request, user)
except FileLockException: except LockError:
weblate.logger.error('failed to lock backend for %s!', self) weblate.logger.error('failed to lock backend for %s!', self)
messages.error( messages.error(
request, request,
......
...@@ -184,6 +184,16 @@ def get_versions(): ...@@ -184,6 +184,16 @@ def get_versions():
'3.1.0', '3.1.0',
)) ))
name = 'lockfile'
url = 'https://pypi.python.org/pypi/lockfile'
mod = get_version_module('lockfile', name, url, True)
result.append((
name,
url,
'N/A',
'',
))
return result return result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment