Skip to content

Commit

Permalink
Docs: Add succint overview of limitations of no-services profile
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sphuber committed Jul 18, 2024
1 parent 17dc88c commit 302ec78
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/source/installation/guide_complete.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion docs/source/installation/guide_quick.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <installation:guide-complete:rabbitmq>` and then run ``verdi profile configure-rabbitmq``.

Functionality
-------------

Part of AiiDA's functionality requires a `message broker <https://en.wikipedia.org/wiki/Message_broker>`_, with the default implementation using `RabbitMQ <https://www.rabbitmq.com/>`_.
The message broker is used to allow communication with the :ref:`daemon <topics: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.
Expand Down
3 changes: 2 additions & 1 deletion src/aiida/cmdline/commands/cmd_presto.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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'
Expand Down
3 changes: 2 additions & 1 deletion src/aiida/cmdline/commands/cmd_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions src/aiida/cmdline/commands/cmd_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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(
Expand Down
5 changes: 3 additions & 2 deletions src/aiida/cmdline/commands/cmd_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand Down
8 changes: 7 additions & 1 deletion src/aiida/cmdline/utils/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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)
4 changes: 4 additions & 0 deletions src/aiida/common/docs.py
Original file line number Diff line number Diff line change
@@ -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'
5 changes: 4 additions & 1 deletion src/aiida/engine/daemon/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/aiida/engine/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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'
Expand Down

0 comments on commit 302ec78

Please sign in to comment.