# HG changeset patch
# User John Schneiderman
# Date 1425930139 -3600
# Node ID 8ef24a759bf60cf938bfda2a9ceb32c078a5bfd6
# Parent 27b2e19955c3eed18bf13b75f14669bb759c90bd
Replaced the generic file locker with a custom repository locker.
diff -r 27b2e19955c3 -r 8ef24a759bf6 INSTALL
--- a/INSTALL Thu Jan 08 18:58:03 2015 +0100
+++ b/INSTALL Mon Mar 09 20:42:19 2015 +0100
@@ -21,13 +21,11 @@
Needed for compiling
====================
1) Python 2.7+
-2) FileLock from https://github.com/dmfrey/FileLock
How To compile the program
============================
-1) Build and install FileLock to site-packages if not already present.
-2) setup.py build
-3) setup.py install
+1) setup.py build
+2) setup.py install
Known Issues
============
diff -r 27b2e19955c3 -r 8ef24a759bf6 doc/ChangeLog
--- a/doc/ChangeLog Thu Jan 08 18:58:03 2015 +0100
+++ b/doc/ChangeLog Mon Mar 09 20:42:19 2015 +0100
@@ -17,6 +17,8 @@
*** You should have received a copy of the GNU Affero General Public License***
*** along with this program. If not, see . ***
********************************************************************************
+2015-00-00 John Schneiderman 0.4.0
+- No longer dependant upon third-party general file locker for repositories.
2014-08-21 John Schneiderman 0.3.0
- Unregistering repositories will now only do so on an exact match of the
storage name.
diff -r 27b2e19955c3 -r 8ef24a759bf6 src/manager.py
--- a/src/manager.py Thu Jan 08 18:58:03 2015 +0100
+++ b/src/manager.py Mon Mar 09 20:42:19 2015 +0100
@@ -45,12 +45,9 @@
import sys
import os
import shutil
- import filelock as guard
import stat
- print "Acquiring manager lock ..."
- lock = guard.FileLock('HWM')
- with lock:
+ with RepositoryManagerLock():
print "Adding repository: %s" % repository.StorageName
if __doesRepositoryStorageNameExist(repository):
print >>sys.stderr, "The repository storage name '%s' already exists." % repository.StorageName
@@ -100,12 +97,7 @@
@return When the registration is successful gives true, else-wise false.
"""
- import sys
- import filelock as guard
-
- print "Acquiring manager lock ..."
- lock = guard.FileLock('HWM')
- with lock:
+ with RepositoryManagerLock():
print "Registering the repository: %s" % repository.StorageName
if not __doesRepositoryStorageNameExist(repository):
print >>sys.stderr, "The repository '%s' does not exists." % repository.StorageName
@@ -140,11 +132,8 @@
"""
import sys
from manrepo import Repository
- import filelock as guard
- print "Acquiring manager lock ..."
- lock = guard.FileLock('HWM')
- with lock:
+ with RepositoryManagerLock():
print "Modifying repository: %s" % currentStorageName
oldRepository = Repository(currentStorageName)
@@ -216,12 +205,7 @@
@return When the deletion is successful gives true, else-wise false.
"""
- import sys
- import filelock as guard
-
- print "Acquiring manager lock ..."
- lock = guard.FileLock('HWM')
- with lock:
+ with RepositoryManagerLock():
if not __doesRepositoryStorageNameExist(repository):
print >>sys.stderr, "The repository %s was not found." % repository.StorageName
return False
diff -r 27b2e19955c3 -r 8ef24a759bf6 src/manrepolock.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/manrepolock.py Mon Mar 09 20:42:19 2015 +0100
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+'''*****************************************************************************
+*** This file is part of HgWeb Manager. ***
+*** ***
+*** Copyright (C) 2014 ***
+*** CodeGNU Solutions ***
+*** ***
+*** This program is free software: you can redistribute it and/or modify it ***
+*** under the terms of the GNU Affero General Public License as published ***
+*** by the Free Software Foundation, either version 3 of the License, or ***
+*** (at your option) any later version. ***
+*** ***
+*** This program is distributed in the hope that it will be useful, but ***
+*** WITHOUT ANY WARRANTY; without even the implied warranty of ***
+*** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ***
+*** See the GNU Affero General Public License for more details. ***
+*** ***
+*** You should have received a copy of the GNU Affero General Public License***
+*** along with this program. If not, see . ***
+*****************************************************************************'''
+
+import errno
+import os
+import tempfile
+import time
+
+
+repositoryLockFile = os.path.join(tempfile.gettempdir(), 'HWM.lock')
+
+
+class RepositoryManagerLock(object):
+ """ Handles the locking for the repository manager. """
+
+ def __init__(self):
+ """ Initialises the lock for use, but does not get one. """
+ self.haveLock = False
+
+ def __isLockedProcessRunning(self):
+ """ Determines if a process is already running
+
+ @return When the process is running gives true, false else-wise.
+ """
+ try:
+ with open(repositoryLockFile) as previousLock:
+ pid = int(previousLock.readline())
+ os.kill(pid, 0)
+ return True
+ except OSError:
+ return False # Process is not running.
+
+ def acquire(self):
+ """ Gets the repository lock. """
+ while True:
+ try:
+ print 'Acquiring repository manager lock ...'
+ self.lock = os.open(repositoryLockFile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+ break
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ if not self.__isLockedProcessRunning():
+ print 'A dead repository lock found, removing ...'
+ os.unlink(repositoryLockFile)
+ time.sleep(0.75)
+ self.haveLock = True
+ os.write(self.lock, str(os.getpid()))
+
+ def release(self):
+ """ Frees the repository lock. """
+ if self.haveLock:
+ print 'Releasing repository manager lock ...'
+ os.close(self.lock)
+ os.unlink(repositoryLockFile)
+ self.haveLock = False
+
+ def __enter__(self):
+ if not self.haveLock:
+ self.acquire()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ if self.haveLock:
+ self.release()
+
+ def __del__(self):
+ """ Ensures that when the object is gone, the lock is released. """
+ self.release()