Skip to content

Commit

Permalink
perf: Faster bench remove-app
Browse files Browse the repository at this point in the history
Biggest bottleneck is in the validation stage which checks if the app is
installed on any existing sites on the bench. instead of triggering
multiple list-apps for each sites, do one for all.
  • Loading branch information
gavindsouza committed May 5, 2021
1 parent 70c9c17 commit ebc3ceb
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions bench/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# imports - standard imports
import json
from json.decoder import JSONDecodeError
import logging
import os
import re
Expand Down Expand Up @@ -202,13 +203,56 @@ def remove_app(app, bench_path='.'):
import shutil
from bench.config.common_site_config import get_config

app_path = os.path.join(bench_path, 'apps', app)
py = os.path.join(bench_path, 'env', 'bin', 'python')

# validate app removal
if app not in get_apps(bench_path):
print("No app named {0}".format(app))
sys.exit(1)

app_path = os.path.join(bench_path, 'apps', app)
validate_app_installed_on_sites(app, bench_path=bench_path)

# remove app from bench
exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path)
remove_from_appstxt(app, bench_path)
shutil.rmtree(app_path)

# re-build assets and restart processes
run_frappe_cmd("build", bench_path=bench_path)
if get_config(bench_path).get('restart_supervisor_on_update'):
restart_supervisor_processes(bench_path=bench_path)
if get_config(bench_path).get('restart_systemd_on_update'):
restart_systemd_processes(bench_path=bench_path)


def validate_app_installed_on_sites(app, bench_path="."):
print("Checking if app installed on active sites...")
ret = check_app_installed(app, bench_path=bench_path)

if ret is None:
check_app_installed_legacy(app, bench_path=bench_path)
else:
return ret


def check_app_installed(app, bench_path="."):
out = subprocess.check_output(["bench", "--site", "all", "list-apps", "--format", "json"], cwd=bench_path).decode('utf-8')

try:
import json
apps_sites_dict = json.loads(out)
except JSONDecodeError:
return None

for site, apps in apps_sites_dict.items():
if app in apps:
print("Cannot remove, app is installed on site: {0}".format(site))
sys.exit(1)


def check_app_installed_legacy(app, bench_path="."):
site_path = os.path.join(bench_path, 'sites')
py = os.path.join(bench_path, 'env', 'bin', 'python')

for site in os.listdir(site_path):
req_file = os.path.join(site_path, site, 'site_config.json')
Expand All @@ -218,14 +262,6 @@ def remove_app(app, bench_path='.'):
print("Cannot remove, app is installed on site: {0}".format(site))
sys.exit(1)

exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path)
remove_from_appstxt(app, bench_path)
shutil.rmtree(app_path)
run_frappe_cmd("build", bench_path=bench_path)
if get_config(bench_path).get('restart_supervisor_on_update'):
restart_supervisor_processes(bench_path=bench_path)
if get_config(bench_path).get('restart_systemd_on_update'):
restart_systemd_processes(bench_path=bench_path)

def pull_apps(apps=None, bench_path='.', reset=False):
'''Check all apps if there no local changes, pull'''
Expand Down

0 comments on commit ebc3ceb

Please sign in to comment.