Мне удалось собрать воедино рабочую демонстрацию службы pywin32 windows, работающей flask внутри wsgi-сервера pylons waitress (ниже). Самостоятельное решение - это идея ..
Я потратил часы на изучение и тестирование способов сделать выход официантки чистым (например, это и это ), но лучший До сих пор я могу сказать, что это своего рода самоубийственный SIGINT, который заставляет Windows жаловаться, что «канал завершен» при остановке через панель управления службами, но, по крайней мере, он останавливается: - / Я предполагаю, что pythonservice.exe, который запускает pywin32, не должен заканчиваться, только официантка ступает?
Если честно, я все еще не уверен, если это вопрос официантке, pywin32, или, может быть, это просто python. Я делаю чувствую, что ответ прямо передо мной, но сейчас я совершенно ошарашен.
Любые предложения приветствуются!
import os
import random
import signal
import socket
from flask import Flask, escape, request
import servicemanager
import win32event
import win32service
import win32serviceutil
from waitress import serve
app = Flask(__name__)
@app.route('/')
def hello():
random.seed()
x = random.randint(1, 1000000)
name = request.args.get("name", "World")
return 'Hello, %s! - %s - %s' % (escape(name), x, os.getpid())
# based on https://www.thepythoncorner.com/2018/08/how-to-create-a-windows-service-in-python/
class SMWinservice(win32serviceutil.ServiceFramework):
'''Base class to create winservice in Python'''
_svc_name_ = 'WaitressService'
_svc_display_name_ = 'Waitress server'
_svc_description_ = 'Python waitress WSGI service'
@classmethod
def parse_command_line(cls):
'''
ClassMethod to parse the command line
'''
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
'''
Constructor of the winservice
'''
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
'''
Called when the service is asked to stop
'''
self.stop()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
'''
Called when the service is asked to start
'''
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def start(self):
pass
def stop(self):
print 'sigint'
os.kill(os.getpid(), signal.SIGINT)
def main(self):
print 'serve'
serve(app, listen='*:5000')
if __name__ == '__main__':
SMWinservice.parse_command_line()