Skip to content

Commit

Permalink
👌 IMPROVE: CLI responsiveness (#5080)
Browse files Browse the repository at this point in the history
This commit improves the CLI loading speed,
by loading the `verdi computer configure` commands
(which in-turn load Transport plugins)
only when necessary.

The strictness of the `verdi devel check-load-time`
is also increased, to only allow loading of specific aiida modules.
  • Loading branch information
chrisjsewell authored Aug 15, 2021
1 parent c24ae31 commit 3a6c77e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 11 deletions.
27 changes: 20 additions & 7 deletions aiida/cmdline/commands/cmd_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
from aiida.cmdline.params.options.commands import computer as options_computer
from aiida.cmdline.utils import echo
from aiida.cmdline.utils.decorators import with_dbenv
from aiida.common.exceptions import ValidationError
from aiida.common.exceptions import ValidationError, EntryPointError
from aiida.plugins.entry_point import get_entry_point_names
from aiida.transports import cli as transport_cli


@verdi.group('computer')
Expand Down Expand Up @@ -539,7 +538,24 @@ def computer_delete(computer):
echo.echo_success(f"Computer '{label}' deleted.")


@verdi_computer.group('configure')
class LazyConfigureGroup(click.Group):
"""A click group that will lazily load the subcommands for each transport plugin."""

def list_commands(self, ctx):
subcommands = super().list_commands(ctx)
subcommands.extend(get_entry_point_names('aiida.transports'))
return subcommands

def get_command(self, ctx, name): # pylint: disable=arguments-differ
from aiida.transports import cli as transport_cli
try:
command = transport_cli.create_configure_cmd(name)
except EntryPointError:
command = super().get_command(ctx, name)
return command


@verdi_computer.group('configure', cls=LazyConfigureGroup)
def computer_configure():
"""Configure the Authinfo details for a computer (and user)."""

Expand All @@ -556,6 +572,7 @@ def computer_configure():
def computer_config_show(computer, user, defaults, as_option_string):
"""Show the current configuration for a computer."""
from aiida.common.escaping import escape_for_bash
from aiida.transports import cli as transport_cli

transport_cls = computer.get_transport_class()
option_list = [
Expand Down Expand Up @@ -595,7 +612,3 @@ def computer_config_show(computer, user, defaults, as_option_string):
else:
table.append((f'* {name}', '-'))
echo.echo(tabulate.tabulate(table, tablefmt='plain'))


for ep_name in get_entry_point_names('aiida.transports'):
computer_configure.add_command(transport_cli.create_configure_cmd(ep_name))
19 changes: 15 additions & 4 deletions aiida/cmdline/commands/cmd_devel.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import sys

from aiida.cmdline.commands.cmd_verdi import verdi
from aiida.cmdline.params import options
from aiida.cmdline.utils import decorators, echo


Expand All @@ -20,26 +21,36 @@ def verdi_devel():


@verdi_devel.command('check-load-time')
def devel_check_load_time():
@options.VERBOSE()
def devel_check_load_time(verbose):
"""Check for common indicators that slowdown `verdi`.
Check for environment properties that negatively affect the responsiveness of the `verdi` command line interface.
Known pathways that increase load time:
* the database environment is loaded when it doesn't need to be
* the `aiida.orm` module is imported when it doesn't need to be
* Unexpected `aiida.*` modules are imported
If either of these conditions are true, the command will raise a critical error
"""
from aiida.manage.manager import get_manager

loaded_aiida_modules = [key for key in sys.modules if key.startswith('aiida.')]
aiida_modules_str = '\n- '.join(sorted(loaded_aiida_modules))
if verbose:
echo.echo(f'aiida modules loaded:\n- {aiida_modules_str}')

manager = get_manager()

if manager.backend_loaded:
echo.echo_critical('potential `verdi` speed problem: database backend is loaded.')

if 'aiida.orm' in sys.modules:
echo.echo_critical('potential `verdi` speed problem: `aiida.orm` module is imported.')
allowed = ('aiida.backends', 'aiida.cmdline', 'aiida.common', 'aiida.manage', 'aiida.plugins', 'aiida.restapi')
for loaded in loaded_aiida_modules:
if not any(loaded.startswith(mod) for mod in allowed):
echo.echo_critical(
f'potential `verdi` speed problem: `{loaded}` module is imported which is not in: {allowed}'
)

echo.echo_success('no issues detected')

Expand Down
1 change: 1 addition & 0 deletions docs/source/nitpick-exceptions
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,4 @@ py:class Session
py:class Query
py:class BackendQueryBuilder
py:class importlib_metadata.EntryPoint
py:class Command

0 comments on commit 3a6c77e

Please sign in to comment.