mirror of
https://github.com/morpheus65535/bazarr
synced 2024-12-21 23:32:31 +00:00
Fixed improper closing of resources on exit
This commit is contained in:
parent
c17d127323
commit
0807bd99b9
7 changed files with 64 additions and 47 deletions
21
bazarr.py
21
bazarr.py
|
@ -52,22 +52,27 @@ dir_name = os.path.dirname(__file__)
|
||||||
|
|
||||||
def end_child_process(ep):
|
def end_child_process(ep):
|
||||||
try:
|
try:
|
||||||
ep.kill()
|
if os.name != 'nt':
|
||||||
|
try:
|
||||||
|
ep.send_signal(signal.SIGINT)
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
import win32api
|
||||||
|
import win32con
|
||||||
|
try:
|
||||||
|
win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, ep.pid)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
except:
|
except:
|
||||||
pass
|
|
||||||
|
|
||||||
def terminate_child_process(ep):
|
|
||||||
try:
|
|
||||||
ep.terminate()
|
ep.terminate()
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def start_bazarr():
|
def start_bazarr():
|
||||||
script = [get_python_path(), "-u", os.path.normcase(os.path.join(dir_name, 'bazarr', 'main.py'))] + sys.argv[1:]
|
script = [get_python_path(), "-u", os.path.normcase(os.path.join(dir_name, 'bazarr', 'main.py'))] + sys.argv[1:]
|
||||||
ep = subprocess.Popen(script, stdout=None, stderr=None, stdin=subprocess.DEVNULL)
|
ep = subprocess.Popen(script, stdout=None, stderr=None, stdin=subprocess.DEVNULL)
|
||||||
atexit.register(end_child_process, ep=ep)
|
atexit.register(end_child_process, ep=ep)
|
||||||
signal.signal(signal.SIGTERM, lambda signal_no, frame: terminate_child_process(ep))
|
signal.signal(signal.SIGTERM, lambda signal_no, frame: end_child_process(ep))
|
||||||
|
|
||||||
|
|
||||||
def check_status():
|
def check_status():
|
||||||
|
|
|
@ -5,6 +5,7 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import flask_migrate
|
import flask_migrate
|
||||||
|
import signal
|
||||||
|
|
||||||
from dogpile.cache import make_region
|
from dogpile.cache import make_region
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -12,7 +13,7 @@ from datetime import datetime
|
||||||
from sqlalchemy import create_engine, inspect, DateTime, ForeignKey, Integer, LargeBinary, Text, func, text, BigInteger
|
from sqlalchemy import create_engine, inspect, DateTime, ForeignKey, Integer, LargeBinary, Text, func, text, BigInteger
|
||||||
# importing here to be indirectly imported in other modules later
|
# importing here to be indirectly imported in other modules later
|
||||||
from sqlalchemy import update, delete, select, func # noqa W0611
|
from sqlalchemy import update, delete, select, func # noqa W0611
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapped_column
|
from sqlalchemy.orm import scoped_session, sessionmaker, mapped_column, close_all_sessions
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.pool import NullPool
|
from sqlalchemy.pool import NullPool
|
||||||
|
|
||||||
|
@ -74,11 +75,18 @@ session_factory = sessionmaker(bind=engine)
|
||||||
database = scoped_session(session_factory)
|
database = scoped_session(session_factory)
|
||||||
|
|
||||||
|
|
||||||
|
def close_database():
|
||||||
|
close_all_sessions()
|
||||||
|
engine.dispose()
|
||||||
|
|
||||||
|
|
||||||
@atexit.register
|
@atexit.register
|
||||||
def _stop_worker_threads():
|
def _stop_worker_threads():
|
||||||
database.remove()
|
database.remove()
|
||||||
|
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, lambda signal_no, frame: close_database())
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
metadata = Base.metadata
|
metadata = Base.metadata
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from api import api_bp
|
||||||
from .ui import ui_bp
|
from .ui import ui_bp
|
||||||
from .get_args import args
|
from .get_args import args
|
||||||
from .config import settings, base_url
|
from .config import settings, base_url
|
||||||
from .database import database
|
from .database import close_database
|
||||||
from .app import create_app
|
from .app import create_app
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
@ -63,49 +63,40 @@ class Server:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
logging.info(f'BAZARR is started and waiting for request on http://{self.server.effective_host}:'
|
||||||
|
f'{self.server.effective_port}')
|
||||||
try:
|
try:
|
||||||
logging.info(f'BAZARR is started and waiting for request on http://{self.server.effective_host}:'
|
self.server.run()
|
||||||
f'{self.server.effective_port}')
|
except (KeyboardInterrupt, SystemExit):
|
||||||
try:
|
|
||||||
self.server.run()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
try:
|
try:
|
||||||
self.server.close()
|
stop_file = io.open(os.path.join(args.config_dir, "bazarr.stop"), "w", encoding='UTF-8')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f'BAZARR Cannot stop Waitress: {repr(e)}')
|
logging.error(f'BAZARR Cannot create stop file: {repr(e)}')
|
||||||
else:
|
else:
|
||||||
database.close()
|
logging.info('Bazarr is being shutdown...')
|
||||||
try:
|
stop_file.write(str(''))
|
||||||
stop_file = io.open(os.path.join(args.config_dir, "bazarr.stop"), "w", encoding='UTF-8')
|
stop_file.close()
|
||||||
except Exception as e:
|
close_database()
|
||||||
logging.error(f'BAZARR Cannot create stop file: {repr(e)}')
|
self.server.close()
|
||||||
else:
|
os._exit(0)
|
||||||
logging.info('Bazarr is being shutdown...')
|
|
||||||
stop_file.write(str(''))
|
|
||||||
stop_file.close()
|
|
||||||
os._exit(0)
|
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
try:
|
try:
|
||||||
self.server.close()
|
restart_file = io.open(os.path.join(args.config_dir, "bazarr.restart"), "w", encoding='UTF-8')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f'BAZARR Cannot stop Waitress: {repr(e)}')
|
logging.error(f'BAZARR Cannot create restart file: {repr(e)}')
|
||||||
else:
|
else:
|
||||||
database.close()
|
logging.info('Bazarr is being restarted...')
|
||||||
try:
|
restart_file.write(str(''))
|
||||||
restart_file = io.open(os.path.join(args.config_dir, "bazarr.restart"), "w", encoding='UTF-8')
|
restart_file.close()
|
||||||
except Exception as e:
|
close_database()
|
||||||
logging.error(f'BAZARR Cannot create restart file: {repr(e)}')
|
self.server.close()
|
||||||
else:
|
os._exit(0)
|
||||||
logging.info('Bazarr is being restarted...')
|
|
||||||
restart_file.write(str(''))
|
|
||||||
restart_file.close()
|
|
||||||
os._exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
webserver = Server()
|
webserver = Server()
|
||||||
|
|
|
@ -340,14 +340,20 @@ def consume_queue(queue):
|
||||||
data = queue.popleft()
|
data = queue.popleft()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
except (KeyboardInterrupt, SystemExit):
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
dispatcher(data)
|
dispatcher(data)
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
# start both queue consuming threads
|
# start both queue consuming threads
|
||||||
threading.Thread(target=consume_queue, args=(sonarr_queue,)).start()
|
sonarr_queue_thread = threading.Thread(target=consume_queue, args=(sonarr_queue,))
|
||||||
threading.Thread(target=consume_queue, args=(radarr_queue,)).start()
|
sonarr_queue_thread.daemon = True
|
||||||
|
sonarr_queue_thread.start()
|
||||||
|
radarr_queue_thread = threading.Thread(target=consume_queue, args=(radarr_queue,))
|
||||||
|
radarr_queue_thread.daemon = True
|
||||||
|
radarr_queue_thread.start()
|
||||||
|
|
||||||
# instantiate proper SignalR client
|
# instantiate proper SignalR client
|
||||||
sonarr_signalr_client = SonarrSignalrClientLegacy() if get_sonarr_info.version().startswith(('0.', '2.', '3.')) else \
|
sonarr_signalr_client = SonarrSignalrClientLegacy() if get_sonarr_info.version().startswith(('0.', '2.', '3.')) else \
|
||||||
|
|
|
@ -77,6 +77,8 @@ def is_virtualenv():
|
||||||
# deploy requirements.txt
|
# deploy requirements.txt
|
||||||
if not args.no_update:
|
if not args.no_update:
|
||||||
try:
|
try:
|
||||||
|
if os.name == 'nt':
|
||||||
|
import win32api, win32con # noqa E401
|
||||||
import lxml, numpy, webrtcvad, setuptools, PIL # noqa E401
|
import lxml, numpy, webrtcvad, setuptools, PIL # noqa E401
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import io
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
|
@ -75,9 +73,15 @@ update_notifier()
|
||||||
|
|
||||||
if not args.no_signalr:
|
if not args.no_signalr:
|
||||||
if settings.general.use_sonarr:
|
if settings.general.use_sonarr:
|
||||||
Thread(target=sonarr_signalr_client.start).start()
|
sonarr_signalr_thread = Thread(target=sonarr_signalr_client.start)
|
||||||
|
sonarr_signalr_thread.daemon = True
|
||||||
|
sonarr_signalr_thread.start()
|
||||||
|
sonarr_signalr_thread.join()
|
||||||
if settings.general.use_radarr:
|
if settings.general.use_radarr:
|
||||||
Thread(target=radarr_signalr_client.start).start()
|
radarr_signalr_thread = Thread(target=radarr_signalr_client.start)
|
||||||
|
radarr_signalr_thread.daemon = True
|
||||||
|
radarr_signalr_thread.start()
|
||||||
|
radarr_signalr_thread.join()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -3,3 +3,4 @@ lxml>=4.3.0, <5.0.0
|
||||||
numpy>=1.12.0
|
numpy>=1.12.0
|
||||||
webrtcvad-wheels>=2.0.10
|
webrtcvad-wheels>=2.0.10
|
||||||
Pillow>=9.0.0 --only-binary=Pillow
|
Pillow>=9.0.0 --only-binary=Pillow
|
||||||
|
pywin32; platform_system == "Windows"
|
||||||
|
|
Loading…
Reference in a new issue