Skip to content

Commit

Permalink
new OperationManager with queue management
Browse files Browse the repository at this point in the history
and thread safe
  • Loading branch information
mirkobrombin committed Dec 21, 2021
1 parent 4ac94d8 commit 29567a1
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 48 deletions.
23 changes: 16 additions & 7 deletions src/backend/backup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os
import yaml
import uuid
import tarfile
import shutil
from typing import NewType
from gettext import gettext as _
from gi.repository import GLib

from .manager import Manager

Expand Down Expand Up @@ -39,6 +41,7 @@ def export_backup(
It returns True if the backup was successful, False otherwise.
'''
BackupManager.operation_manager = OperationManager(window)
task_id = str(uuid.uuid4())

if scope == "config":
logging.info(
Expand All @@ -56,9 +59,11 @@ def export_backup(
logging.info(
f"Backuping bottle: [{config['Name']}] in [{path}]"
)
task_entry = BackupManager.operation_manager.new_task(
file_name=_("Backup {0}").format(config.get("Name")),
cancellable=False
GLib.idle_add(
BackupManager.operation_manager.new_task,
task_id,
_("Backup {0}").format(config.get("Name")),
False
)
bottle_path = ManagerUtils.get_bottle_path(config)
try:
Expand All @@ -71,7 +76,7 @@ def export_backup(
except:
backup_created = False

task_entry.remove()
GLib.idle_add(BackupManager.operation_manager.remove_task, task_id)

if backup_created:
logging.info(f"Backup saved in path: {path}.")
Expand All @@ -91,11 +96,15 @@ def import_backup(window, scope: str, path: str, manager: Manager) -> bool:
will also update the bottles' list), False otherwise.
'''
BackupManager.operation_manager = OperationManager(window)
task_id = str(uuid.uuid4())
backup_name = path.split("/")[-1].split(".")
import_status = False

task_entry = BackupManager.operation_manager.new_task(
_("Importing backup: {0}").format(backup_name), False
GLib.idle_add(
BackupManager.operation_manager.new_task,
task_id,
_("Importing backup: {0}").format(backup_name),
False
)
logging.info(f"Importing backup: {backup_name}")

Expand Down Expand Up @@ -129,7 +138,7 @@ def import_backup(window, scope: str, path: str, manager: Manager) -> bool:
except:
import_status = False

task_entry.remove()
GLib.idle_add(BackupManager.operation_manager.remove_task, task_id)

if import_status:
window.manager.update_bottles()
Expand Down
27 changes: 15 additions & 12 deletions src/backend/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import os
import yaml
import uuid
import shutil
import tarfile
import requests
Expand Down Expand Up @@ -192,11 +193,12 @@ def download(
Add new entry to the download manager and set the update_func
to the task_entry update_status function by default.
'''
task_entry = self.__operation_manager.new_task(
file_name=file,
cancellable=False
task_id = str(uuid.uuid4())
GLib.idle_add(
self.__operation_manager.new_task, task_id, file, False
)
_update_func = task_entry.update_status

_update_func = self.__operation_manager.update_task

if download_url.startswith("temp/"):
'''
Expand All @@ -213,12 +215,13 @@ def download(
_update_func = func

def update_func(
task_id,
count=False,
block_size=False,
total_size=False,
completed=False
):
GLib.idle_add(_update_func, count, block_size, total_size, completed)
GLib.idle_add(_update_func, task_id, count, block_size, total_size, completed)

existing_file = rename if rename else file
just_downloaded = False
Expand All @@ -232,7 +235,7 @@ def update_func(
logging.warning(
f"File [{existing_file}] already exists in temp, skipping."
)
GLib.idle_add(update_func, False, False, False, True)
GLib.idle_add(update_func, task_id, False, False, False, True)
else:
'''
As some urls can be redirect, we need to take care of this
Expand All @@ -245,7 +248,7 @@ def update_func(
download_url = response.url
req_code = urllib.request.urlopen(download_url).getcode()
except:
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return False

if req_code == 200:
Expand All @@ -261,20 +264,20 @@ def update_func(
func=update_func
).download()
except:
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return False

if not os.path.isfile(f"{Paths.temp}/{file}"):
'''
If the file is not available in the /temp directory,
then the download failed.
'''
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return False

just_downloaded = True
else:
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return False

if rename and just_downloaded:
Expand Down Expand Up @@ -304,10 +307,10 @@ def update_func(
os.remove(file_path)

#os.remove(file_path)
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return False

GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return True

def extract(self, name: str, component: str, archive: str) -> True:
Expand Down
17 changes: 9 additions & 8 deletions src/backend/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import os
import yaml
import uuid
import shutil
import patoolib
from glob import glob
Expand Down Expand Up @@ -115,6 +116,7 @@ def install(
This function install a given dependency in a bottle. It will
return True if the installation was successful.
'''
task_id = str(uuid.uuid4())
uninstaller = True

if config["Versioning"]:
Expand All @@ -129,9 +131,8 @@ def install(
update=True
)

task_entry = self.__operation_manager.new_task(
file_name=dependency[0],
cancellable=False
GLib.idle_add(
self.__operation_manager.new_task, task_id, dependency[0], False
)

logging.info(
Expand All @@ -149,7 +150,7 @@ def install(
If the manifest is not found, return a Result
object with the error.
'''
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return Result(
status=False,
message=f"Cannot find manifest for {dependency[0]}."
Expand All @@ -162,7 +163,7 @@ def install(
'''
res = self.__perform_steps(config, step)
if not res.status:
GLib.idle_add(task_entry.remove)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
return Result(
status=False,
message=f"One or more steps failed for {dependency[0]}."
Expand Down Expand Up @@ -202,8 +203,8 @@ def install(
"Uninstallers"
)

# Remove entry from download manager
GLib.idle_add(task_entry.remove)
# Remove entry from operation manager
GLib.idle_add(self.__operation_manager.remove_task, task_id)

# Hide installation button and show remove button
if not uninstaller:
Expand Down Expand Up @@ -244,7 +245,7 @@ def __perform_steps(
return Result(status=False)

if step["action"] == "uninstall":
self.__step_uninstall(config=config, file_name=step["file_name"])
self.__step_uninstall(config=config, title=step["file_name"])

if step["action"] == "cab_extract":
uninstaller = False
Expand Down
43 changes: 30 additions & 13 deletions src/backend/versioning.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import yaml
import uuid
import shutil
from glob import glob
from typing import NewType
Expand All @@ -25,7 +26,7 @@ class RunnerVersioning:
def __init__(self, window, manager):
self.window = window
self.manager = manager
self.operation_manager = OperationManager(self.window)
self.__operation_manager = OperationManager(self.window)

def create_state(
self,
Expand All @@ -42,14 +43,17 @@ def create_state(
the index file. It will return True if the state was created,
False otherwise.
'''
task_id = str(uuid.uuid4())
logging.info(
f"Creating new state for bottle: [{config['Name']}] …"
)

bottle_path = ManagerUtils.get_bottle_path(config)
task_entry = self.operation_manager.new_task(
file_name=_("Generating state files index …"),
cancellable=False
GLib.idle_add(
self.__operation_manager.new_task,
task_id,
_("Generating state files index …"),
False
)

# check if this is the first state
Expand Down Expand Up @@ -129,9 +133,14 @@ def create_state(
state_id = 0

state_path = "%s/states/%s" % (bottle_path, state_id)
task_entry.remove()
task_entry = self.operation_manager.new_task(
_("Creating a restore point …"), False)

GLib.idle_add(self.__operation_manager.remove_task, task_id)
GLib.idle_add(
self.__operation_manager.new_task,
task_id,
_("Creating a restore point …"),
False
)

try:
'''
Expand All @@ -156,9 +165,13 @@ def create_state(
message=_("Could not create the state folder.")
)

task_entry.remove()
task_entry = self.operation_manager.new_task(
_("Updating index …"), False)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
GLib.idle_add(
self.__operation_manager.new_task,
task_id,
_("Updating index …"),
False
)

for file in cur_index["Files"]:
'''
Expand All @@ -176,9 +189,13 @@ def create_state(
target = "{0}/drive_c/{1}".format(state_path, file["file"])
shutil.copyfile(source, target)

task_entry.remove()
task_entry = self.operation_manager.new_task(
_("Updating states …"), False)
GLib.idle_add(self.__operation_manager.remove_task, task_id)
GLib.idle_add(
self.__operation_manager.new_task,
task_id,
_("Updating states …"),
False
)

# update the states.yml file, appending the new state
new_state = {
Expand Down
Loading

0 comments on commit 29567a1

Please sign in to comment.