Преглед на файлове

Use our own pidfile mechanism, don't need full lockfile support as the granularity we need is by main process.

Ask Solem преди 15 години
родител
ревизия
0ab2e9bacc
променени са 1 файла, в които са добавени 53 реда и са изтрити 25 реда
  1. 53 25
      celery/platform.py

+ 53 - 25
celery/platform.py

@@ -3,6 +3,7 @@ import sys
 import pwd
 import grp
 import signal
+from contextlib import contextmanager
 try:
     from setproctitle import setproctitle as _setproctitle
 except ImportError:
@@ -35,10 +36,19 @@ def maybe_remove_file(path, ignore_perm_denied=False):
         raise
 
 
-def remove_pidlock(pidfile):
-    """Remove pidfile created by :class:`daemon.pidlockfile.PIDLockFile`."""
-    maybe_remove_file(pidfile)
-    maybe_remove_file("%s.lock" % pidfile)
+@contextmanager
+def pidlockfile(pidfile):
+    from daemon import pidlockfile
+    import lockfile
+
+    try:
+        pidlockfile.write_pid_to_pidfile(pidfile)
+    except OSError, exc:
+        raise lockfile.LockFailed(str(exc))
+
+    yield
+
+    maybe_remove_file(pidfile, ignore_perm_denied=True)
 
 
 def acquire_pidlock(pidfile):
@@ -52,33 +62,51 @@ def acquire_pidlock(pidfile):
     running in the background somewhere.
 
     """
-    from daemon.pidlockfile import PIDLockFile as _PIDLockFile
-    from lockfile import LinkFileLock
+    from daemon import pidlockfile
+    from lockfile import LinkFileLock, LockFailed
     import errno
 
-    class SafeRemovePIDLockFile(_PIDLockFile):
+    class SafeRemovePIDLockFile(pidlockfile.PIDLockFile):
+
+        def __init__(self, path, threaded=True):
+            self.abspath = os.path.abspath(path)
+            super(SafeRemovePIDLockFile, self).__init__(path, threaded)
+
+        def is_locked(self):
+            return os.path.exists(self.abspath)
+
+        def i_am_locking(self):
+            return self.is_locked()
+
+        def acquire(self, timeout=None):
+            try:
+                pidlockfile.write_pid_to_pidfile(self.abspath)
+            except OSError, exc:
+                raise LockFailed(str(exc))
 
         def release(self):
-            if self.i_am_locking():
-                maybe_remove_file(self.path, ignore_perm_denied=True)
-            LinkFileLock.release(self)
+            maybe_remove_file(self.abspath, ignore_perm_denied=True)
+
+        def break_lock(self):
+            self.release()
+
+        def is_stale(self):
+            pid = pidlock.read_pid()
+            try:
+                os.kill(pid, 0)
+            except os.error, exc:
+                if exc.errno == errno.ESRCH:
+                    sys.stderr.write("Stale pidfile exists. Removing it.\n")
+                    self.release()
+                    return True
+            except TypeError, exc:
+                sys.stderr.write("Broken pidfile found. Removing it.\n")
+                self.release()
+                return True
+            return False
 
     pidlock = SafeRemovePIDLockFile(pidfile)
-    if not pidlock.is_locked():
-        return pidlock
-    pid = pidlock.read_pid()
-    try:
-        os.kill(pid, 0)
-    except os.error, exc:
-        if exc.errno == errno.ESRCH:
-            sys.stderr.write("Stale pidfile exists. Removing it.\n")
-            remove_pidlock(pidfile)
-            return SafeRemovePIDLockFile(pidfile)
-    except TypeError, exc:
-        sys.stderr.write("Broken pidfile found. Removing it.\n")
-        remove_pidlock(pidfile)
-        return SafeRemovePIDLockFile(pidfile)
-    else:
+    if pidlock.is_locked() and not pidlock.is_stale():
         raise SystemExit(
                 "ERROR: Pidfile (%s) already exists.\n"
                 "Seems celeryd is already running? (PID: %d)" % (