@xibolba

Как грамотно управлять процессом через веб интерфейс?

Задача управлять сторонним процессом (пуск, стоп, перезапуск). Можно ли обойтись без глобальной переменной? Т.к. питон не умеет перезапускать процессы встает необходимость запуска через новый экземпляр класса. Пример бы увидеть хорошего кода.

from multiprocessing import Process
from live_detect import live_detection
from flask import Flask, jsonify
from flask_limiter import Limiter, RequestLimit
from flask_limiter.util import get_remote_address

app = Flask(__name__)

limiter = Limiter(
    key_func=get_remote_address,
    app=app,
    storage_uri="memory://",
)


def ratelimit_start_stop_error(request_limit: RequestLimit):
    return jsonify({"error": "Don't spam? please!"})


@app.route("/")
def hello_world():
    try:
        pid = current_process.pid
        status = current_process.is_alive()
    except:
        pid = None
        status = False
    if status:
        return '<form action="/detection/stop"><input type="submit" value="stop"/></form>' \
               f'<p>is running: {status}</p>' \
               f'<p>pid: {pid}</p>'
    else:
        return '<form action="/detection/start"><input type="submit" value="start"/></form>' \
               f'<p>is running: {status}</p>'


def fu_new_process_start():
    detection = Process(target=live_detection)
    detection.daemon = True
    detection.start()
    return detection


def fu_current_process_is_live():
    return current_process.is_alive()


@app.route("/detection/start")
@limiter.limit('1 per second', on_breach=ratelimit_start_stop_error)
def start_detection():
    try:
        status = fu_current_process_is_live()
    except:
        status = False

    global current_process

    if status is False:
        try:
            current_process = fu_new_process_start()
            return "<p>Started Detection!</p>" \
                   '<form action="/"><input type="submit" value="home"/></form>'
        except Exception as e:
            return f"<p>Error!</p><p>{e}</p>" \
                   '<form action="/"><input type="submit" value="home"/></form>'
    else:
        return f"<p>Error!</p><p>Детектирование уже запущено!</p>" \
               '<form action="/"><input type="submit" value="home"/></form>'


@app.route("/detection/stop")
@limiter.limit('1 per second', on_breach=ratelimit_start_stop_error)
def stop_detection():
    try:
        current_process.terminate()
        return "<p>Stopped Detection!</p>" \
               '<form action="/"><input type="submit" value="home"/></form>'
    except Exception as e:
        return f"<p>Error!</p><p>{e}</p>" \
               '<form action="/"><input type="submit" value="home"/></form>'


if __name__ == '__main__':
    app.run()
  • Вопрос задан
  • 122 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Everything_is_bad
Полностью разделить веб сервис и контролируемый процесс, например, сделать его отдельным сервисом в systemd, тогда можно будет управлять им через команды systemctl.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы