spacepaste

  1.  
  2. """Generic linux daemon base class for python 3.x."""
  3. import uuid
  4. import sys
  5. import os
  6. import time
  7. import threading
  8. class daemon(object):
  9. """A generic daemon class.
  10. Usage: subclass the daemon class and override the run() method."""
  11. def __init__(self):
  12. self._thread = threading.Thread(target=self.test, name='task_queue', daemon=True)
  13. def test(self):
  14. for i in range(3):
  15. print('running loop %s' % i)
  16. time.sleep(1)
  17. def daemonize(self):
  18. """Daemonizes the current process. Returns the new pid"""
  19. try:
  20. pid = os.fork()
  21. if pid > 0:
  22. # exit first parent
  23. sys.exit(0)
  24. except OSError as err:
  25. sys.stderr.write('fork #1 failed: {0}\n'.format(err))
  26. sys.exit(1)
  27. # decouple from parent environment
  28. os.chdir('/')
  29. os.setsid()
  30. os.umask(0)
  31. print('First fork pid %s' % os.getpid())
  32. # do second fork
  33. try:
  34. pid = os.fork()
  35. if pid > 0:
  36. # exit from second parent
  37. sys.exit(0)
  38. except OSError as err:
  39. sys.stderr.write('fork #2 failed: {0}\n'.format(err))
  40. sys.exit(1)
  41. # redirect standard file descriptors
  42. sys.stdout.flush()
  43. sys.stderr.flush()
  44. si = open(os.devnull, 'r')
  45. so = open('/tmp/file', 'a+')
  46. se = open('/tmp/file', 'a+')
  47. os.dup2(si.fileno(), sys.stdin.fileno())
  48. os.dup2(so.fileno(), sys.stdout.fileno())
  49. os.dup2(se.fileno(), sys.stderr.fileno())
  50. def start(self):
  51. """Start the daemon."""
  52. # Start the daemon
  53. self.daemonize()
  54. self._thread.start()
  55. self.wait()
  56. def wait(self):
  57. """
  58. Waits for the thread to exit.
  59. Allows abortion of task queue with ctrl-c
  60. """
  61. try:
  62. print('thread alive is %s' % self._thread.is_alive())
  63. while self._thread.is_alive():
  64. print('pid %s wait sleep thread alive is %s' % (os.getpid(), self._thread.is_alive()))
  65. time.sleep(0.5)
  66. except KeyboardInterrupt:
  67. print('Got ctrl-c, shutting down after running task (if any) completes')
  68. # We still wait to finish cleanly, pressing ctrl-c again will abort
  69. while self._thread.is_alive():
  70. time.sleep(0.5)
  71. d = daemon()
  72. d.start()
  73.