Created
June 23, 2014 01:58
-
-
Save allanlei/03a464c15b521c58d862 to your computer and use it in GitHub Desktop.
Windows Celery Service: Source https://stackoverflow.com/questions/9378932/how-to-create-celery-windows-service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
The most basic (working) Windows service possible. | |
Requires Mark Hammond's pywin32 package. | |
Most of the code was taken from a CherryPy 2.2 example of how to set up a service | |
""" | |
import pkg_resources | |
import win32serviceutil | |
from paste.script.serve import ServeCommand as Server | |
import os, sys | |
import ConfigParser | |
import win32service | |
import win32event | |
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) | |
INI_FILE = 'celeryd.ini' | |
SERV_SECTION = 'celery:service' | |
SERV_NAME = 'service_name' | |
SERV_DISPLAY_NAME = 'service_display_name' | |
SERV_DESC = 'service_description' | |
SERV_LOG_FILE = 'service_logfile' | |
SERV_APPLICATION = 'celeryd' | |
SERV_LOG_FILE_VAR = 'CELERYD_LOG_FILE' | |
# Default Values | |
SERV_NAME_DEFAULT = 'CeleryService' | |
SERV_DISPLAY_NAME_DEFAULT = 'Celery Service' | |
SERV_DESC_DEFAULT = 'WSCGI Windows Celery Service' | |
SERV_LOG_FILE_DEFAULT = r'D:\logs\celery.log' | |
class DefaultSettings(object): | |
def __init__(self): | |
if SCRIPT_DIR: | |
os.chdir(SCRIPT_DIR) | |
# find the ini file | |
self.ini = os.path.join(SCRIPT_DIR,INI_FILE) | |
# create a config parser opject and populate it with the ini file | |
c = ConfigParser.SafeConfigParser() | |
c.read(self.ini) | |
self.c = c | |
def getDefaults(self): | |
''' | |
Check for and get the default settings | |
''' | |
if ( | |
(not self.c.has_section(SERV_SECTION)) or | |
(not self.c.has_option(SERV_SECTION, SERV_NAME)) or | |
(not self.c.has_option(SERV_SECTION, SERV_DISPLAY_NAME)) or | |
(not self.c.has_option(SERV_SECTION, SERV_DESC)) or | |
(not self.c.has_option(SERV_SECTION, SERV_LOG_FILE)) | |
): | |
print 'setting defaults' | |
self.setDefaults() | |
service_name = self.c.get(SERV_SECTION, SERV_NAME) | |
service_display_name = self.c.get(SERV_SECTION, SERV_DISPLAY_NAME) | |
service_description = self.c.get(SERV_SECTION, SERV_DESC) | |
iniFile = self.ini | |
service_logfile = self.c.get(SERV_SECTION, SERV_LOG_FILE) | |
return service_name, service_display_name, service_description, iniFile, service_logfile | |
def setDefaults(self): | |
''' | |
set and add the default setting to the ini file | |
''' | |
if not self.c.has_section(SERV_SECTION): | |
self.c.add_section(SERV_SECTION) | |
self.c.set(SERV_SECTION, SERV_NAME, SERV_NAME_DEFAULT) | |
self.c.set(SERV_SECTION, SERV_DISPLAY_NAME, SERV_DISPLAY_NAME_DEFAULT) | |
self.c.set(SERV_SECTION, SERV_DESC, SERV_DESC_DEFAULT) | |
self.c.set(SERV_SECTION, SERV_LOG_FILE, SERV_LOG_FILE_DEFAULT) | |
cfg = file(self.ini, 'wr') | |
self.c.write(cfg) | |
cfg.close() | |
print ''' | |
you must set the celery:service section service_name, service_display_name, | |
and service_description options to define the service | |
in the %s file | |
''' % self.ini | |
sys.exit() | |
class CeleryService(win32serviceutil.ServiceFramework): | |
"""NT Service.""" | |
d = DefaultSettings() | |
service_name, service_display_name, service_description, iniFile, logFile = d.getDefaults() | |
_svc_name_ = service_name | |
_svc_display_name_ = service_display_name | |
_svc_description_ = service_description | |
def __init__(self, args): | |
win32serviceutil.ServiceFramework.__init__(self, args) | |
# create an event that SvcDoRun can wait on and SvcStop | |
# can set. | |
self.stop_event = win32event.CreateEvent(None, 0, 0, None) | |
def SvcDoRun(self): | |
os.chdir(SCRIPT_DIR) | |
s = Server(SERV_APPLICATION) | |
os.environ[SERV_LOG_FILE_VAR] = self.logFile | |
s.run([self.iniFile]) | |
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE) | |
def SvcStop(self): | |
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) | |
#win32event.SetEvent(self.stop_event) | |
self.ReportServiceStatus(win32service.SERVICE_STOPPED) | |
sys.exit() | |
if __name__ == '__main__': | |
win32serviceutil.HandleCommandLine(CeleryService) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment