增加线程启停

This commit is contained in:
EstrellaXD
2023-05-09 23:17:09 +08:00
parent bfba4d1dda
commit f3c2aeded8
4 changed files with 115 additions and 59 deletions

View File

@@ -1,83 +1,103 @@
import os
import signal
import logging
import uvicorn
import multiprocessing
import threading
import time
from fastapi import Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from module import app
from module.api import router
from module.conf import VERSION, settings
from module.conf import VERSION, settings, setup_logger
from module.rss import RSSAnalyser
from module.conf.uvicorn_logging import logging_config
logger = logging.getLogger(__name__)
main_process = multiprocessing.Process(target=app.run, args=(settings,))
stop_event = threading.Event()
rss_link = settings.rss_link()
def rss_loop(stop_event, rss_link: str):
rss_analyser = RSSAnalyser()
while not stop_event.is_set():
rss_analyser.run(rss_link)
logger.info("RSS loop finished.")
stop_event.wait(settings.program.sleep_time)
rss_thread = threading.Thread(
target=rss_loop,
args=(stop_event, rss_link),
)
@router.on_event("startup")
async def startup():
global main_process
main_process.start()
global rss_thread
setup_logger()
rss_thread = threading.Thread(
target=rss_loop,
args=(stop_event, rss_link),
)
rss_thread.start()
@router.on_event("shutdown")
async def shutdown():
global main_process
if main_process.is_alive():
os.kill(main_process.pid, signal.SIGTERM)
stop_event.set()
logger.info("Stopping RSS analyser...")
@router.get("/api/v1/restart", tags=["program"])
async def restart():
global main_process
if main_process.is_alive():
os.kill(main_process.pid, signal.SIGTERM)
logger.info("Restarting...")
else:
logger.info("Starting...")
settings.reload()
main_process = multiprocessing.Process(target=app.run, args=(settings,))
main_process.start()
logger.info("Restarted")
return {"status": "success"}
@router.get("/api/v1/stop", tags=["program"])
async def stop():
global main_process
if not main_process.is_alive():
return {"status": "failed", "reason": "Already stopped"}
logger.info("Stopping...")
os.kill(main_process.pid, signal.SIGTERM)
logger.info("Stopped")
return {"status": "success"}
global rss_thread
if not rss_thread.is_alive():
return {"status": "Already stopped."}
stop_event.set()
logger.info("Stopping RSS analyser...")
rss_thread.join()
stop_event.clear()
time.sleep(1)
settings.load()
rss_link = settings.rss_link()
if "://" not in rss_link:
rss_link = f"https://{rss_link}"
rss_thread = threading.Thread(
target=rss_loop,
args=(stop_event, rss_link),
)
rss_thread.start()
return {"status": "ok"}
@router.get("/api/v1/start", tags=["program"])
async def start():
global main_process
if main_process.is_alive():
return {"status": "failed", "reason": "Already started"}
logger.info("Starting...")
settings.reload()
main_process = multiprocessing.Process(target=app.run, args=(settings,))
main_process.start()
logger.info("Started")
return {"status": "success"}
global rss_thread
if rss_thread.is_alive():
return {"status": "Already started."}
rss_thread = threading.Thread(
target=rss_loop,
args=(stop_event, rss_link),
)
rss_thread.start()
return {"status": "ok"}
@router.get("/api/v1/status", tags=["program"])
async def status():
global main_process
if main_process.is_alive():
return True
else:
return False
@router.get("/api/v1/stop", tags=["program"])
async def stop():
global rss_thread
if not rss_thread.is_alive():
return {"status": "Already stopped."}
stop_event.set()
logger.info("Stopping RSS analyser...")
rss_thread.join()
stop_event.clear()
return {"status": "ok"}
if VERSION != "DEV_VERSION":
@@ -98,10 +118,6 @@ else:
if __name__ == "__main__":
log_config = uvicorn.config.LOGGING_CONFIG
log_config["formatters"]["default"][
"fmt"
] = "[%(asctime)s] %(levelname)-8s %(message)s"
uvicorn.run(
router, host="0.0.0.0", port=settings.program.webui_port, log_config=log_config
router, host="0.0.0.0", port=settings.program.webui_port
)

View File

@@ -0,0 +1,40 @@
logging_config = {
"version": 1,
"disable_existing_loggers": False,
"loggers": {
"uvicorn.error": {
"level": "INFO",
"handlers": ["default"],
"propagate": True,
},
"uvicorn.access": {
"level": "INFO",
"handlers": ["access"],
"propagate": True,
},
},
"handlers": {
"default": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "default",
"stream": "ext://sys.stderr",
},
"access": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "access",
"stream": "ext://sys.stdout",
},
},
"formatters": {
"default": {
"format": "[%(asctime)s] %(levelname)s: %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
"access": {
"format": "[%(asctime)s] %(levelname)s: %(client_addr)s - \"%(request_line)s\" %(status_code)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
}

View File

@@ -17,20 +17,20 @@ logger = logging.getLogger(__name__)
class APIProcess:
def __init__(self, settings: Config):
self._rss_analyser = RSSAnalyser(settings)
self._client = DownloadClient(settings)
self._rss_analyser = RSSAnalyser()
self._client = DownloadClient()
self._full_season_get = FullSeasonGet(settings)
self._custom_url = settings.rss_parser.custom_url
def link_process(self, link):
return self._rss_analyser.rss_to_data(link, _filter=False)
return self._rss_analyser.rss_to_data(link)
@api_failed
def download_collection(self, link):
if not self._client.authed:
self._client.auth()
data = self.link_process(link)
self._full_season_get.download_collection(data, link, self._client)
self._full_season_get.download_collection(data, link)
return data
@api_failed

View File

@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
class FullSeasonGet(DownloadClient):
def __init__(self, settings: Config):
super().__init__(settings)
super().__init__()
self.SEARCH_KEY = [
"group",
"title_raw",