crunchd 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. sys.path.append(os.getcwd())
  5. from django.conf import settings
  6. from crunchy.platform import PIDFile, daemonize, remove_pidfile
  7. from crunchy.log import setup_logger
  8. from crunchy.conf import LOG_LEVELS, DAEMON_LOG_FILE, DAEMON_LOG_LEVEL
  9. from crunchy.conf import DAEMON_CONCURRENCY, DAEMON_PID_FILE
  10. from crunchy.conf import QUEUE_WAKEUP_AFTER
  11. from crunchy import discovery
  12. from crunchy.worker import TaskDaemon
  13. import traceback
  14. import optparse
  15. import atexit
  16. def main(concurrency=DAEMON_CONCURRENCY, daemon=False,
  17. loglevel=DAEMON_LOG_LEVEL, logfile=DAEMON_LOG_FILE,
  18. pidfile=DAEMON_PID_FILE, queue_wakeup_after=QUEUE_WAKEUP_AFTER):
  19. if settings.DATABASE_ENGINE == "sqlite3" and concurrency > 1:
  20. import warnings
  21. warnings.warn("The sqlite3 database engine doesn't support "
  22. "concurrency. We'll be using a single process only.",
  23. UserWarning)
  24. concurrency = 1
  25. if daemon:
  26. sys.stderr.write("Launching crunchd in the background...\n")
  27. pidfile_handler = PIDFile(pidfile)
  28. pidfile_handler.check()
  29. daemonize(pidfile=pidfile_handler)
  30. atexit.register(remove_pidfile, pidfile)
  31. else:
  32. logfile = None # log to stderr when not running as daemon.
  33. discovery.autodiscover()
  34. crunchd = TaskDaemon(concurrency=concurrency,
  35. loglevel=loglevel,
  36. logfile=logfile,
  37. queue_wakeup_after=queue_wakeup_after)
  38. try:
  39. crunchd.run()
  40. except Exception, e:
  41. raise
  42. emergency_error(logfile, "crunchd raised exception %s: %s\n%s" % (
  43. e.__class__, e, traceback.format_exc()))
  44. def parse_options(arguments):
  45. parser = optparse.OptionParser()
  46. parser.add_option('-c', '--concurrency', default=DAEMON_CONCURRENCY,
  47. action="store", dest="concurrency", type="int",
  48. help="Number of child processes processing the queue.")
  49. parser.add_option('-f', '--logfile', default=DAEMON_LOG_FILE,
  50. action="store", dest="logfile",
  51. help="Path to log file.")
  52. parser.add_option('-l', '--loglevel', default=DAEMON_LOG_LEVEL,
  53. action="store", dest="loglevel",
  54. help="Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL/FATAL.")
  55. parser.add_option('-p', '--pidfile', default=DAEMON_PID_FILE,
  56. action="store", dest="pidfile",
  57. help="Path to PID file.")
  58. parser.add_option('-w', '--wakeup-after', default=QUEUE_WAKEUP_AFTER,
  59. action="store", dest="queue_wakeup_after",
  60. help="If the queue is empty, this is the time *in seconds* the "
  61. "daemon sleeps until it wakes up to check if there's any "
  62. "new messages on the queue.")
  63. parser.add_option('-d', '--daemon', default=False,
  64. action="store_true", dest="daemon",
  65. help="Run in background as a daemon.")
  66. options, values = parser.parse_args(arguments)
  67. if not isinstance(options.loglevel, int):
  68. options.loglevel = LOG_LEVELS[options.loglevel.upper()]
  69. return options
  70. if __name__ == "__main__":
  71. options = parse_options(sys.argv[1:])
  72. main(concurrency=options.concurrency,
  73. daemon=options.daemon,
  74. logfile=options.logfile,
  75. loglevel=options.loglevel,
  76. pidfile=options.pidfile,
  77. queue_wakeup_after=options.queue_wakeup_after)