From 8f3cc69e5d4a26f2b10d0ac14261e5de709ac272 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Mon, 25 Nov 2019 16:03:56 -0300 Subject: [PATCH] [improvements][appimage] AppImage updater daemon replaced by a default Python thread to reduce memory usage --- CHANGELOG.md | 4 +++- README.md | 2 +- bauh/gems/appimage/controller.py | 13 ++++++------- bauh/gems/appimage/db.py | 18 ------------------ bauh/gems/appimage/worker.py | 18 ++++++++++-------- 5 files changed, 20 insertions(+), 35 deletions(-) delete mode 100644 bauh/gems/appimage/db.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e65a9dc6..fd38bc2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.7.3] +## [0.7.3] 2019- ### Improvements - Not breaking the application when a i18n (translation) key was not found - Adding all english (**en**) i18n keys to help people with the application translation +- AppImage: + - AppImage updater daemon replaced by a default Python thread to reduce memory usage ## [0.7.2] 2019-11-01 ### Improvements diff --git a/README.md b/README.md index 84a97bd1..f02b4cdd 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings - Installed applications are store at **~/.local/share/bauh/appimage/installed** - Desktop entries ( menu shortcuts ) of the installed applications are stored at **~/.local/share/applications** - Downloaded database files are stored at **~/.local/share/bauh/appimage** as **apps.db** and **releases.db** -- Databases updater daemon running every 20 minutes. It can be disabled via the environment variable **BAUH_APPIMAGE_DB_UPDATER=0**. +- Databases updater daemon running every 20 minutes ( the interval in SECONDS can be changed with the environment variable **BAUH_APPIMAGE_DB_UPDATER_TIME** ). It can be disabled via the environment variable **BAUH_APPIMAGE_DB_UPDATER=0**. - All supported application names can be found at: https://github.com/vinifmor/bauh-files/blob/master/appimage/apps.txt Obs: There are some crashes when **AppImageLauncher** is installed. It is advisable to uninstall it and reboot the system before trying to install an AppImage application. diff --git a/bauh/gems/appimage/controller.py b/bauh/gems/appimage/controller.py index 1f5ab7f9..77aef8f1 100644 --- a/bauh/gems/appimage/controller.py +++ b/bauh/gems/appimage/controller.py @@ -7,6 +7,7 @@ import subprocess import traceback from datetime import datetime from pathlib import Path +from threading import Lock from typing import Set, Type, List from bauh.api.abstract.context import ApplicationContext @@ -18,7 +19,7 @@ from bauh.api.abstract.view import MessageType from bauh.api.constants import HOME_PATH from bauh.commons.html import bold from bauh.commons.system import SystemProcess, new_subprocess, ProcessHandler, run_cmd, SimpleProcess -from bauh.gems.appimage import query, INSTALLATION_PATH, suggestions, db +from bauh.gems.appimage import query, INSTALLATION_PATH, suggestions from bauh.gems.appimage.model import AppImage from bauh.gems.appimage.worker import DatabaseUpdater @@ -43,18 +44,19 @@ class AppImageManager(SoftwareManager): self.http_client = context.http_client self.logger = context.logger self.file_downloader = context.file_downloader - self.dbs_updater = DatabaseUpdater(http_client=context.http_client, logger=context.logger) + self.db_locks = {DB_APPS_PATH: Lock(), DB_RELEASES_PATH: Lock()} + self.dbs_updater = DatabaseUpdater(http_client=context.http_client, logger=context.logger, db_locks=self.db_locks) def _get_db_connection(self, db_path: str) -> sqlite3.Connection: if os.path.exists(db_path): - db.acquire_lock(db_path) + self.db_locks[db_path].acquire() return sqlite3.connect(db_path) else: self.logger.warning("Could not get a database connection. File '{}' not found".format(db_path)) def _close_connection(self, db_path: str, con: sqlite3.Connection): con.close() - db.release_lock(db_path) + self.db_locks[db_path].release() def _gen_app_key(self, app: AppImage): return '{}{}'.format(app.name.lower(), app.github.lower() if app.github else '') @@ -380,9 +382,6 @@ class AppImageManager(SoftwareManager): return False def prepare(self): - for path in (DB_APPS_PATH, DB_RELEASES_PATH): - db.release_lock(path) - self.dbs_updater.start() def list_updates(self, internet_available: bool) -> List[PackageUpdate]: diff --git a/bauh/gems/appimage/db.py b/bauh/gems/appimage/db.py deleted file mode 100644 index d4b81cfe..00000000 --- a/bauh/gems/appimage/db.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -import time - - -def acquire_lock(db_path: str): - lock_path = db_path + '.lock' - while True: - if not os.path.exists(lock_path): - open(lock_path, 'a').close() - break - else: - time.sleep(0.0001) - - -def release_lock(db_path: str): - lock_path = db_path + '.lock' - if os.path.exists(lock_path): - os.remove(lock_path) diff --git a/bauh/gems/appimage/worker.py b/bauh/gems/appimage/worker.py index e9449cbe..1dbb108f 100644 --- a/bauh/gems/appimage/worker.py +++ b/bauh/gems/appimage/worker.py @@ -4,27 +4,27 @@ import os import tarfile import time import traceback -from multiprocessing import Process from pathlib import Path from threading import Thread import requests from bauh.api.http import HttpClient -from bauh.gems.appimage import LOCAL_PATH, db +from bauh.gems.appimage import LOCAL_PATH -class DatabaseUpdater(Thread if bool(int(os.getenv('BAUH_DEBUG', 0))) else Process): +class DatabaseUpdater(Thread): URL_DB = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/appimage/dbs.tar.gz' COMPRESS_FILE_PATH = LOCAL_PATH + '/db.tar.gz' - def __init__(self, http_client: HttpClient, logger: logging.Logger): + def __init__(self, http_client: HttpClient, logger: logging.Logger, db_locks: dict): super(DatabaseUpdater, self).__init__(daemon=True) self.http_client = http_client self.logger = logger self.enabled = bool(int(os.getenv('BAUH_APPIMAGE_DB_UPDATER', 1))) - self.sleep = 60 * 20 + self.db_locks = db_locks + self.sleep = int(os.getenv('BAUH_APPIMAGE_DB_UPDATER_TIME', 60 * 20)) def _download_databases(self): self.logger.info('Retrieving AppImage databases') @@ -44,9 +44,11 @@ class DatabaseUpdater(Thread if bool(int(os.getenv('BAUH_DEBUG', 0))) else Proce if old_db_files: self.logger.info('Deleting old database files') for f in old_db_files: - db.acquire_lock(f) - os.remove(f) - db.release_lock(f) + self.db_locks[f].acquire() + try: + os.remove(f) + finally: + self.db_locks[f].release() self.logger.info('Old database files deleted')