From 4038d550452df25cccd13137b9dfb5823345c544 Mon Sep 17 00:00:00 2001 From: Sebastiaan Huber Date: Thu, 18 Jul 2024 14:04:38 +0200 Subject: [PATCH] Docs: Add succint overview of limitations of no-services profile A table is added to the quick installation guide that gives a more succinct overview of the limitations of a profile created without a broker and with SQLite instead of PostgreSQL. This was already explained in more detail in text, but that was not complete and could be too dense for users, making them likely to skip it. The code is updated to provide a link to this documentation section whenever an error is displayed that a broker is not configured. This way users can try to understand why the functionality they are trying to use is not supported and how, if they really care about it, they can go about still installing and configuring RabbitMQ after the fact. --- docs/source/installation/guide_complete.rst | 2 +- docs/source/installation/guide_quick.rst | 20 +++++++++++++++++++- src/aiida/cmdline/commands/cmd_presto.py | 3 ++- src/aiida/cmdline/commands/cmd_process.py | 3 ++- src/aiida/cmdline/commands/cmd_profile.py | 2 ++ src/aiida/cmdline/commands/cmd_status.py | 5 +++-- src/aiida/cmdline/utils/decorators.py | 8 +++++++- src/aiida/common/docs.py | 4 ++++ src/aiida/engine/daemon/client.py | 5 ++++- src/aiida/engine/launch.py | 5 ++++- 10 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 src/aiida/common/docs.py diff --git a/docs/source/installation/guide_complete.rst b/docs/source/installation/guide_complete.rst index 49136bbba7..764274616d 100644 --- a/docs/source/installation/guide_complete.rst +++ b/docs/source/installation/guide_complete.rst @@ -130,7 +130,7 @@ Although it is possible to run AiiDA without a daemon it does provide significan .. important:: The ``aiida-core.services`` package ensures that RabbitMQ is installed in the conda environment. - However, it is not a _service_, in the sense that it is not automatically started, but has to be started manually. + However, it is not a *service*, in the sense that it is not automatically started, but has to be started manually. .. code-block:: console diff --git a/docs/source/installation/guide_quick.rst b/docs/source/installation/guide_quick.rst index af9aaa8dc0..25ef307d57 100644 --- a/docs/source/installation/guide_quick.rst +++ b/docs/source/installation/guide_quick.rst @@ -51,13 +51,31 @@ If none of the lines show a red cross, indicating a problem, the installation wa Quick install limitations ========================= +By default, ``verdi presto`` creates a profile that uses SQLite instead of PostgreSQL and does not use the RabbitMQ message broker. +The table below gives a quick overview of the functionality that is not supported in those cases: + ++-----------------------------------------+------------------------------------------------------------------------+ +| No RabbitMQ | SQLite instead of PostgreSQL | ++=========================================+========================================================================+ +| Cannot run the daemon | Not suitable for high-throughput workloads | ++-----------------------------------------+------------------------------------------------------------------------+ +| Cannot submit processes to the daemon\* | No support for ``has_key`` and ``contains`` operators in query builder | ++-----------------------------------------+------------------------------------------------------------------------+ +| Cannot play, pause, kill processes | No support for ``QueryBuilder.get_creation_statistics`` | ++-----------------------------------------+------------------------------------------------------------------------+ + +\* Calculations can still be run on remote computers + +.. note:: + To enable the RabbitMQ broker for an existing profile, :ref:`install RabbitMQ ` and then run ``verdi profile configure-rabbitmq``. + Functionality ------------- Part of AiiDA's functionality requires a `message broker `_, with the default implementation using `RabbitMQ `_. The message broker is used to allow communication with the :ref:`daemon `. Since RabbitMQ is a separate service and is not always trivial to install, the quick installation guide sets up a profile that does not require it. -As a result, the daemon cannot be started and processes cannot be submitted to it but can only be run locally. +As a result, the daemon cannot be started and processes cannot be submitted to it but can only be run in the current Python interpreter. .. note:: The ``verdi presto`` command automatically checks if RabbitMQ is running on the localhost. diff --git a/src/aiida/cmdline/commands/cmd_presto.py b/src/aiida/cmdline/commands/cmd_presto.py index 83ba287a94..09d7070e7c 100644 --- a/src/aiida/cmdline/commands/cmd_presto.py +++ b/src/aiida/cmdline/commands/cmd_presto.py @@ -178,7 +178,7 @@ def verdi_presto( created profile uses the new PostgreSQL database instead of SQLite. """ from aiida.brokers.rabbitmq.defaults import detect_rabbitmq_config - from aiida.common import exceptions + from aiida.common import docs, exceptions from aiida.manage.configuration import create_profile, load_profile from aiida.orm import Computer @@ -217,6 +217,7 @@ def verdi_presto( broker_config = detect_rabbitmq_config() except ConnectionError as exception: echo.echo_report(f'RabbitMQ server not found ({exception}): configuring the profile without a broker.') + echo.echo_report(f'See {docs.URL_NO_BROKER} for details on the limitations of running without a broker.') else: echo.echo_report('RabbitMQ server detected: configuring the profile with a broker.') broker_backend = 'core.rabbitmq' diff --git a/src/aiida/cmdline/commands/cmd_process.py b/src/aiida/cmdline/commands/cmd_process.py index 77e14a3300..c9c492ae14 100644 --- a/src/aiida/cmdline/commands/cmd_process.py +++ b/src/aiida/cmdline/commands/cmd_process.py @@ -101,6 +101,7 @@ def process_list( from aiida.cmdline.commands.cmd_daemon import execute_client_command from aiida.cmdline.utils.common import print_last_process_state_change + from aiida.common.docs import URL_NO_BROKER from aiida.common.exceptions import ConfigurationError from aiida.engine.daemon.client import get_daemon_client from aiida.orm import ProcessNode, QueryBuilder @@ -137,7 +138,7 @@ def process_list( try: client = get_daemon_client() except ConfigurationError: - echo.echo_warning('This profile does not have a broker and so it has no daemon.') + echo.echo_warning(f'This profile does not have a broker and so it has no daemon. See {URL_NO_BROKER}') return if not client.is_daemon_running: diff --git a/src/aiida/cmdline/commands/cmd_profile.py b/src/aiida/cmdline/commands/cmd_profile.py index 057f2de5a9..3dd21b56bf 100644 --- a/src/aiida/cmdline/commands/cmd_profile.py +++ b/src/aiida/cmdline/commands/cmd_profile.py @@ -55,6 +55,7 @@ def command_create_profile( :param kwargs: Arguments to initialise instance of the selected storage implementation. """ from aiida.brokers.rabbitmq.defaults import detect_rabbitmq_config + from aiida.common import docs from aiida.plugins.entry_point import get_entry_point_from_class if not storage_cls.read_only and email is None: @@ -79,6 +80,7 @@ def command_create_profile( else: echo.echo_report('Creating profile without RabbitMQ.') echo.echo_report('It can be configured at a later point in time with `verdi profile configure-rabbitmq`.') + echo.echo_report(f'See {docs.URL_NO_BROKER} for details on the limitations of running without a broker.') try: profile = create_profile( diff --git a/src/aiida/cmdline/commands/cmd_status.py b/src/aiida/cmdline/commands/cmd_status.py index dc4521af02..f3c32327dc 100644 --- a/src/aiida/cmdline/commands/cmd_status.py +++ b/src/aiida/cmdline/commands/cmd_status.py @@ -58,6 +58,7 @@ class ServiceStatus(enum.IntEnum): def verdi_status(print_traceback, no_rmq): """Print status of AiiDA services.""" from aiida import __version__ + from aiida.common.docs import URL_NO_BROKER from aiida.common.exceptions import ConfigurationError from aiida.engine.daemon.client import DaemonException, DaemonNotRunningException from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER @@ -141,7 +142,7 @@ def verdi_status(print_traceback, no_rmq): print_status( ServiceStatus.WARNING, 'broker', - 'No broker defined for this profile: certain functionality not available.', + f'No broker defined for this profile: certain functionality not available. See {URL_NO_BROKER}', ) # Getting the daemon status @@ -151,7 +152,7 @@ def verdi_status(print_traceback, no_rmq): print_status( ServiceStatus.WARNING, 'daemon', - 'No broker defined for this profile: daemon is not available.', + 'No broker defined for this profile: daemon is not available. See {URL_NO_BROKER}', ) except DaemonNotRunningException as exception: print_status(ServiceStatus.WARNING, 'daemon', str(exception)) diff --git a/src/aiida/cmdline/utils/decorators.py b/src/aiida/cmdline/utils/decorators.py index 84386710f9..5363926978 100644 --- a/src/aiida/cmdline/utils/decorators.py +++ b/src/aiida/cmdline/utils/decorators.py @@ -45,6 +45,7 @@ def with_broker(wrapped, _, args, kwargs): If the currently loaded profile does not define a broker, the command is aborted. """ + from aiida.common.docs import URL_NO_BROKER from aiida.manage import get_manager broker = get_manager().get_broker() @@ -54,6 +55,7 @@ def with_broker(wrapped, _, args, kwargs): if broker is None: echo.echo_critical( f'Profile `{profile.name}` does not support this functionality as it does not provide a broker.' + f'See {URL_NO_BROKER} for more details.' ) kwargs['broker'] = broker @@ -313,6 +315,7 @@ def start_daemon(): If the loaded profile does not define a broker, the command will exit with a critical error. """ + from aiida.common.docs import URL_NO_BROKER from aiida.manage import get_manager manager = get_manager() @@ -323,6 +326,9 @@ def start_daemon(): assert profile is not None if manager.get_broker() is None: - echo.echo_critical(f'profile `{profile.name}` does not define a broker and so cannot use this functionality.') + echo.echo_critical( + f'profile `{profile.name}` does not define a broker and so cannot use this functionality.' + f'See {URL_NO_BROKER} for more details.' + ) return wrapped(*args, **kwargs) diff --git a/src/aiida/common/docs.py b/src/aiida/common/docs.py new file mode 100644 index 0000000000..797c944387 --- /dev/null +++ b/src/aiida/common/docs.py @@ -0,0 +1,4 @@ +"""Collection of links to the documentation that can be used in log messages for reference.""" + +URL_BASE = 'https://aiida-core.readthedocs.io/en/stable' +URL_NO_BROKER = f'{URL_BASE}/installation/guide_quick.html#quick-install-limitations' diff --git a/src/aiida/engine/daemon/client.py b/src/aiida/engine/daemon/client.py index 67ca7b99b5..ef250802f7 100644 --- a/src/aiida/engine/daemon/client.py +++ b/src/aiida/engine/daemon/client.py @@ -91,6 +91,8 @@ def __init__(self, profile: Profile): :param profile: The profile instance. """ + from aiida.common.docs import URL_NO_BROKER + type_check(profile, Profile) config = get_config() self._profile = profile @@ -99,7 +101,8 @@ def __init__(self, profile: Profile): if self._profile.process_control_backend is None: raise ConfigurationError( - f'profile `{self._profile.name}` does not define a broker so the daemon cannot be used.' + f'profile `{self._profile.name}` does not define a broker so the daemon cannot be used. ' + f'See {URL_NO_BROKER} for more details.' ) @property diff --git a/src/aiida/engine/launch.py b/src/aiida/engine/launch.py index d37cf46905..34fd1d7c0d 100644 --- a/src/aiida/engine/launch.py +++ b/src/aiida/engine/launch.py @@ -103,6 +103,8 @@ def submit( :param kwargs: inputs to be passed to the process. This is an alternative to the positional ``inputs`` argument. :return: the calculation node of the process """ + from aiida.common.docs import URL_NO_BROKER + inputs = prepare_inputs(inputs, **kwargs) # Submitting from within another process requires ``self.submit``` unless it is a work function, in which case the @@ -117,7 +119,8 @@ def submit( 'Cannot submit because the runner does not have a process controller, probably because the profile does ' 'not define a broker like RabbitMQ. If a RabbitMQ server is available, the profile can be configured to ' 'use it with `verdi profile configure-rabbitmq`. Otherwise, use :meth:`aiida.engine.launch.run` instead to ' - 'run the process in the local Python interpreter instead of submitting it to the daemon.' + 'run the process in the local Python interpreter instead of submitting it to the daemon. ' + f'See {URL_NO_BROKER} for more details.' ) assert runner.persister is not None, 'runner does not have a persister'