2013-03-22 59 views
35

我想实现一个可以通过使用瓶子脚本来停止瓶应用的命令。 我已经搜索了一段时间的解决方案。由于该框架不提供“app.stop()”API,我很好奇如何对此进行编码。我正在使用Ubuntu 12.10和Python 2.7.3。如何在不使用ctrl-c的情况下停止瓶的应用

+0

为什么你需要能够停止脚本中的应用程序? (这项工作的最佳工具将取决于你想要做什么)。 – 2013-03-22 05:14:51

+0

说真的,你想在这里做什么?如果您正在谈论devserver进行开发,那么停止它就完全没问题。在生产中,您不会像这样部署,您可以随时停止请求,因此“应用程序停止运行”。 – 2013-03-22 05:42:45

+0

@SeanVieira我想知道是否有任何解决方案来做到这一点。 – vrootic 2013-03-22 08:51:01

回答

44

如果你只是运行桌面上的服务器,你可以公开端点杀死服务器(更在Shutdown The Simple Server读):

from flask import request 
def shutdown_server(): 
    func = request.environ.get('werkzeug.server.shutdown') 
    if func is None: 
     raise RuntimeError('Not running with the Werkzeug Server') 
    func() 

@app.route('/shutdown', methods=['POST']) 
def shutdown(): 
    shutdown_server() 
    return 'Server shutting down...' 

这里是另一种方法是多个内含:

from multiprocessing import Process 

server = Process(target=app.run) 
server.start() 
# ... 
server.terminate() 
server.join() 

让我知道这是否有帮助。

+8

您是否知道是否有任何方法可以在不需要请求上下文的情况下获得'werkzeug.server.shutdown'属性? – akatkinson 2014-10-13 04:31:06

+1

我不得不将路由方法更改为“GET”才能使其工作。 – 2016-08-31 20:39:26

+2

为了完整起见,这个答案是缺少你要在请求上下文之外调用关闭的函数,这不过是对服务器的HTTP请求(可以源于/到本地主机) – JamesHutchison 2017-03-04 00:59:52

4

正如其他人指出的那样,您只能从请求处理程序中使用werkzeug.server.shutdown。我发现在另一时间关闭服务器的唯一方法是向您发送请求。

import requests 
from threading import Timer 
import time 

LAST_REQUEST_MS = 0 
@app.before_request 
def update_last_request_ms(): 
    global LAST_REQUEST_MS 
    LAST_REQUEST_MS = time.time() * 1000 


@app.route('/seriouslykill', methods=['POST']) 
def seriouslykill(): 
    func = request.environ.get('werkzeug.server.shutdown') 
    if func is None: 
     raise RuntimeError('Not running with the Werkzeug Server') 
    func() 
    return "Shutting down..." 


@app.route('/kill', methods=['POST']) 
def kill(): 
    last_ms = LAST_REQUEST_MS 
    def shutdown(): 
     if LAST_REQUEST_MS <= last_ms: # subsequent requests abort shutdown 
      requests.post('http://localhost:5000/seriouslykill') 
     else: 
      pass 

    Timer(1.0, shutdown).start() # wait 1 second 
    return "Shutting down..." 
+0

这个工作,但感觉.. _very_ hacky。我知道这已经有一段时间了,但是你有没有找到一个干净的方式来做到这一点,而不向自己发送请求? – Juicy 2017-05-28 20:35:50

2

我的方法可通过bash的终端/主机可以进行

1)运行,并得到:例如,除非另一个请求在下一第二进来的/kill处理程序在这个片段将杀死dev的服务器进程号

$ ps aux | grep yourAppKeywords 

2a)的杀进程

$ kill processNum 

图2b),如果以上不工作

$ kill -9 processNum 
+0

我几乎可以肯定,问题不是“如何杀死一个进程”,问题是做ctrl + c不会杀死它。顺便说一句,我确实使用'kill -9 \'lsof -i:5000 -t''cuz除了1个应用程序可以使用该端口并且非常简单外, – erm3nda 2017-03-29 07:12:31

2

这是一个老问题,但谷歌搜索没有给我如何做到这一点任何见解杀死进程。

因为我没有正确阅读code here! (DOH!) 它的作用是提高RuntimeError时,有在request.environ没有werkzeug.server.shutdown ...

那么,什么时候没有request我们可以做的是提高RuntimeError

def shutdown(): 
    raise RuntimeError("Server going down") 

并在app.run()返回时发现:

... 
try: 
    app.run(host="0.0.0.0") 
except RuntimeError, msg: 
    if str(msg) == "Server going down": 
     pass # or whatever you want to do when the server goes down 
    else: 
     # appropriate handling/logging of other runtime errors 
# and so on 
... 

无需发送自己的请求。

7

我做到了使用线程略有不同

from werkzeug.serving import make_server 

class ServerThread(threading.Thread): 

    def __init__(self, app): 
     threading.Thread.__init__(self) 
     self.srv = make_server('127.0.0.1', 5000, app) 
     self.ctx = app.app_context() 
     self.ctx.push() 

    def run(self): 
     log.info('starting server') 
     self.srv.serve_forever() 

    def shutdown(self): 
     self.srv.shutdown() 

def start_server(): 
    global server 
    app = flask.Flask('myapp') 
    ... 
    server = ServerThread(app) 
    server.start() 
    log.info('server started') 

def stop_server(): 
    global server 
    server.shutdown() 

我用它做端到端的RESTful API,因此在这里我可以给使用Python请求库请求测试。

+0

我没有设法让其他东西工作,但这种解决方案效果很好!万分感谢!对于其他人:它也适用于烧瓶安宁! – 2017-09-04 14:38:59

+0

这似乎阻止在窗户上,直到我用另一个请求打...它以任何方式? – Claudiu 2017-10-12 19:45:41

+0

我和@Claudiu的问题一样,除了使用python 3.6.2的Linux – micahscopes 2017-11-19 00:23:09

相关问题