file_baton.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import os
  2. import time
  3. class FileBaton:
  4. '''A primitive, file-based synchronization utility.'''
  5. def __init__(self, lock_file_path, wait_seconds=0.1):
  6. '''
  7. Creates a new :class:`FileBaton`.
  8. Args:
  9. lock_file_path: The path to the file used for locking.
  10. wait_seconds: The seconds to periorically sleep (spin) when
  11. calling ``wait()``.
  12. '''
  13. self.lock_file_path = lock_file_path
  14. self.wait_seconds = wait_seconds
  15. self.fd = None
  16. def try_acquire(self):
  17. '''
  18. Tries to atomically create a file under exclusive access.
  19. Returns:
  20. True if the file could be created, else False.
  21. '''
  22. try:
  23. self.fd = os.open(self.lock_file_path, os.O_CREAT | os.O_EXCL)
  24. return True
  25. except FileExistsError:
  26. return False
  27. def wait(self):
  28. '''
  29. Periodically sleeps for a certain amount until the baton is released.
  30. The amount of time slept depends on the ``wait_seconds`` parameter
  31. passed to the constructor.
  32. '''
  33. while os.path.exists(self.lock_file_path):
  34. time.sleep(self.wait_seconds)
  35. def release(self):
  36. '''Releases the baton and removes its file.'''
  37. if self.fd is not None:
  38. os.close(self.fd)
  39. os.remove(self.lock_file_path)