PageRenderTime 66ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/gluon/winservice.py

http://github.com/web2py/web2py
Python | 168 lines | 135 code | 17 blank | 16 comment | 10 complexity | 3d1aa150a56bde1ad275005d370cffe0 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, BSD-2-Clause, MPL-2.0-no-copyleft-exception, Apache-2.0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This file is part of the web2py Web Framework
  5. Developed by Massimo Di Pierro <mdipierro@cs.depaul.edu> and
  6. Limodou <limodou@gmail.com>.
  7. License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
  8. This makes uses of the pywin32 package
  9. (http://sourceforge.net/projects/pywin32/).
  10. You do not need to install this package to use web2py.
  11. """
  12. import time
  13. import os
  14. import sys
  15. import traceback
  16. try:
  17. import win32serviceutil
  18. import win32service
  19. import win32event
  20. except:
  21. if os.name == 'nt':
  22. print "Warning, winservice is unable to install the Mark Hammond Win32 extensions"
  23. import servicemanager
  24. import _winreg
  25. from fileutils import up
  26. __all__ = ['web2py_windows_service_handler']
  27. class Service(win32serviceutil.ServiceFramework):
  28. _svc_name_ = '_unNamed'
  29. _svc_display_name_ = '_Service Template'
  30. def __init__(self, *args):
  31. win32serviceutil.ServiceFramework.__init__(self, *args)
  32. self.stop_event = win32event.CreateEvent(None, 0, 0, None)
  33. def log(self, msg):
  34. servicemanager.LogInfoMsg(str(msg))
  35. def SvcDoRun(self):
  36. self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
  37. try:
  38. self.ReportServiceStatus(win32service.SERVICE_RUNNING)
  39. self.start()
  40. win32event.WaitForSingleObject(self.stop_event,
  41. win32event.INFINITE)
  42. except:
  43. self.log(traceback.format_exc(sys.exc_info))
  44. self.SvcStop()
  45. self.ReportServiceStatus(win32service.SERVICE_STOPPED)
  46. def SvcStop(self):
  47. self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
  48. try:
  49. self.stop()
  50. except:
  51. self.log(traceback.format_exc(sys.exc_info))
  52. win32event.SetEvent(self.stop_event)
  53. self.ReportServiceStatus(win32service.SERVICE_STOPPED)
  54. # to be overridden
  55. def start(self):
  56. pass
  57. # to be overridden
  58. def stop(self):
  59. pass
  60. class Web2pyService(Service):
  61. _svc_name_ = 'web2py'
  62. _svc_display_name_ = 'web2py Service'
  63. _exe_args_ = 'options'
  64. server = None
  65. def chdir(self):
  66. try:
  67. h = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
  68. r'SYSTEM\CurrentControlSet\Services\%s'
  69. % self._svc_name_)
  70. try:
  71. cls = _winreg.QueryValue(h, 'PythonClass')
  72. finally:
  73. _winreg.CloseKey(h)
  74. dir = os.path.dirname(cls)
  75. os.chdir(dir)
  76. return True
  77. except:
  78. self.log("Can't change to web2py working path; server is stopped")
  79. return False
  80. def start(self):
  81. self.log('web2py server starting')
  82. if not self.chdir():
  83. return
  84. if len(sys.argv) == 2:
  85. opt_mod = sys.argv[1]
  86. else:
  87. opt_mod = self._exe_args_
  88. options = __import__(opt_mod, [], [], '')
  89. if True: # legacy support for old options files, which have only (deprecated) numthreads
  90. if hasattr(options, 'numthreads') and not hasattr(options, 'minthreads'):
  91. options.minthreads = options.numthreads
  92. if not hasattr(options, 'minthreads'): options.minthreads = None
  93. if not hasattr(options, 'maxthreads'): options.maxthreads = None
  94. import main
  95. self.server = main.HttpServer(
  96. ip=options.ip,
  97. port=options.port,
  98. password=options.password,
  99. pid_filename=options.pid_filename,
  100. log_filename=options.log_filename,
  101. profiler_filename=options.profiler_filename,
  102. ssl_certificate=options.ssl_certificate,
  103. ssl_private_key=options.ssl_private_key,
  104. min_threads=options.minthreads,
  105. max_threads=options.maxthreads,
  106. server_name=options.server_name,
  107. request_queue_size=options.request_queue_size,
  108. timeout=options.timeout,
  109. shutdown_timeout=options.shutdown_timeout,
  110. path=options.folder
  111. )
  112. try:
  113. self.server.start()
  114. except:
  115. # self.server.stop()
  116. self.server = None
  117. raise
  118. def stop(self):
  119. self.log('web2py server stopping')
  120. if not self.chdir():
  121. return
  122. if self.server:
  123. self.server.stop()
  124. time.sleep(1)
  125. def web2py_windows_service_handler(argv=None, opt_file='options'):
  126. path = os.path.dirname(__file__)
  127. classstring = os.path.normpath(os.path.join(up(path),
  128. 'gluon.winservice.Web2pyService'))
  129. if opt_file:
  130. Web2pyService._exe_args_ = opt_file
  131. win32serviceutil.HandleCommandLine(Web2pyService,
  132. serviceClassString=classstring, argv=['', 'install'])
  133. win32serviceutil.HandleCommandLine(Web2pyService,
  134. serviceClassString=classstring, argv=argv)
  135. if __name__ == '__main__':
  136. web2py_windows_service_handler()