summaryrefslogtreecommitdiff
path: root/Mailman/LockFile.py
Commit message (Collapse)AuthorAgeFilesLines
* StaleLockFileError: new exception to handle the case when a lockbwarsaw1999-11-061-1/+25
| | | | | | | | | claimant crashes before cleaning up it's hardlink claim. lock(): There's no reliable way to clean up stale hardlink lockfile claims programmatically, so the best we can do is signal the error and let a human fix the problem. This happens when we've stolen the lock, fail the 2-link test, but happen to be the lockfile winner.
* Several changes to make this a more generally useful module.bwarsaw1999-08-201-64/+148
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Most important: a semantic change. When a lock is acquired, an additional float value is written to the lock file. This is the lock's expected lifetime, as an instant some point in the future (i.e. time.time() + lifetime). This allows processes to give a clue to other claimants as to how long the lock holder intends to keep the lock. This is necessary because the same resource may need to be locked by short lived and long lived processes (e.g. the archiver). Without this, the short lived process has no idea when the lock owner should have given up the lock and could steal it out from under it. It is possible that a process could continually refresh a lock (see below) in an infloop, thus causing all other claimants to back off forever. This is (I believe) much less likely than that a process crashes, leaving a lock turd around. Rename this file to LockFile.py (retain flock.py for CVS archival purposes, but soon all references to this module will be changed to use LockFile instead of flock). The main class in this module is also named LockFile. All the exceptions have been changed to class-based. LockError is the base exception class. AlreadyCalledLockError is changed to AlreadyLockedError but NotLockedError and TimeOutError are not changed. New public methods set_lifetime() and refresh(). The former sets the lifetime interval so that the same lock object can be reused with a different lock lifetime. The latter refreshes the lock lifetime for an already held lock. A process can use this if it suddenly realizes it needs more time to complete its work. "hung_timeout" is renamed to lifetime, because of the changed semantics All private attributes have been __renamed Docstrings everywhere!
* LockFile.lock(): Two changes: first a minor one, if we raise abwarsaw1998-12-271-7/+27
| | | | | | | | | | TimeOutError, we want to unlink our tmpfname first, so we don't potentially leave our linkfile hanging around forever. The second change adds a `stolen' flag which gets set to 1 when we determine a link is stale, and should eliminate the occasional assert errors Ken is seeing. My analysis is included in the comment in the code, but I still wonder if the logic here isn't still flawed.
* Add small comment on assertion, in light of Ken's complaint of 7-Decbwarsaw1998-12-181-0/+5
|
* FileLock.steal(): New method which just basically writes a new PIDbwarsaw1998-12-181-0/+4
| | | | | | | | into the lock file. USE WITH CAUTION. Necessary because in the new news/mail gating code, the parent acquires the lock, and if successful, the child will steal it from the parent and then unlock it when done. This should be safe, with a very small race window, if any.
* __del__(): Only unlock if locked.bwarsaw1998-07-221-1/+2
|
* Several changes, primarily to make this more robust. So far, no morebwarsaw1998-07-221-26/+77
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | locking problems. JV please eyeball... 1. Got rid of is_locked attribute. Test for locking makes an explicit test that a) the tmpfname exists and b) the pid read from the file is our pid. This means that two instances of FileLock in the same process that share the same lockfile will always be locked and unlocked together (probably doesn't occur except in testing). 2. Added an __del__() which unlocks 3. Moved the creation of the basic lockfile to __kickstart() and added a force argument. When force is true (default is false), the lockfile is first removed then recreated. This is only used if the lockfile contains bogus data, such that the winner could not be determined. In that case, the only way to "break" the lock is to recreate a new basic lockfile. This could potentially leave tmpfname turds, but in reality this shouldn't happen very often. 4. Encapsulate reading and writing of the lockfile into __write() and __read(), so that (most importantly) the umask will be set correctly. This should fix most of the permission problems associated with the lockfile by assuring that they are group writable. A side effect: don't eval() the contents of the lockfile. 5. lock(): Use the above changes. Added an assert for what I think is an invariant: that the winner filename better not be equal to self.tmpfname. Moved the timeout check into an else clause of the pid comparison and eliminated the check of hung_timeout > 0 (this is the one I'm least sure about).
* Fixed indentation (so changes look bigger than they really are).bwarsaw1998-07-061-64/+76
| | | | | | Since there's still problems with locking, I added a little better diagnostic to the one os.unlink() exception I've been getting a lot. This should be removed when fixed.
* I removed a potential race condition, if two files decide to time-outviega1998-06-241-13/+17
| | | | | | a lock at the same time. This *may* have been Barry's problem. It should at least fix it (the os.error one), even if I'm not 100% sure of how it is happening.
* Sometimes I miss type checking... fixed a collision between a methodviega1998-06-131-6/+7
| | | | and a variable.
* New file locking class that is, in theory, portable. Since this isviega1998-06-131-0/+100
code that could easily be independant of the Mailman library, I use the Python std lib naming conventions of all lowercase method names instead of the mixed-case way in which most of Mailman is done.