Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Add method to start the daemon to DaemonClient #5625

Merged
merged 1 commit into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 7 additions & 81 deletions aiida/cmdline/commands/cmd_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
# For further information please visit http://www.aiida.net #
###########################################################################
"""`verdi daemon` commands."""

import os
import subprocess
import sys
import time
Expand Down Expand Up @@ -233,7 +231,6 @@ def restart(ctx, reset, no_wait):
from aiida.engine.daemon.client import get_daemon_client

client = get_daemon_client()

wait = not no_wait

if reset:
Expand Down Expand Up @@ -271,84 +268,13 @@ def start_circus(foreground, number):

.. note:: this should not be called directly from the commandline!
"""
from circus import get_arbiter
from circus import logger as circus_logger
from circus.circusd import daemonize
from circus.pidfile import Pidfile
from circus.util import check_future_exception_and_log, configure_logger

from aiida.engine.daemon.client import get_daemon_client
get_daemon_client()._start_daemon(number_workers=number, foreground=foreground) # pylint: disable=protected-access

if foreground and number > 1:
raise click.ClickException('can only run a single worker when running in the foreground')

client = get_daemon_client()

loglevel = client.loglevel
logoutput = '-'

if not foreground:
logoutput = client.circus_log_file

arbiter_config = {
'controller': client.get_controller_endpoint(),
'pubsub_endpoint': client.get_pubsub_endpoint(),
'stats_endpoint': client.get_stats_endpoint(),
'logoutput': logoutput,
'loglevel': loglevel,
'debug': False,
'statsd': True,
'pidfile': client.circus_pid_file,
'watchers': [{
'cmd': client.cmd_string,
'name': client.daemon_name,
'numprocesses': number,
'virtualenv': client.virtualenv,
'copy_env': True,
'stdout_stream': {
'class': 'FileStream',
'filename': client.daemon_log_file,
},
'stderr_stream': {
'class': 'FileStream',
'filename': client.daemon_log_file,
},
'env': get_env_with_venv_bin(),
}]
} # yapf: disable

if not foreground:
daemonize()

arbiter = get_arbiter(**arbiter_config)
pidfile = Pidfile(arbiter.pidfile)

try:
pidfile.create(os.getpid())
except RuntimeError as exception:
echo.echo_critical(str(exception))

# Configure the logger
loggerconfig = None
loggerconfig = loggerconfig or arbiter.loggerconfig or None
configure_logger(circus_logger, loglevel, logoutput, loggerconfig)

# Main loop
should_restart = True

while should_restart:
try:
future = arbiter.start()
should_restart = False
if check_future_exception_and_log(future) is None:
should_restart = arbiter._restarting # pylint: disable=protected-access
except Exception as exception:
# Emergency stop
arbiter.loop.run_sync(arbiter._emergency_stop) # pylint: disable=protected-access
raise exception
except KeyboardInterrupt:
pass
finally:
arbiter = None
if pidfile is not None:
pidfile.unlink()
@verdi_daemon.command('worker')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that you feel this makes more sense as a location - at the same time, have you ever encountered a use case for this that was not related to AiiDA development?

If so, perhaps this use case should be documented in the aiida docs. If not, I guess we could also leave this command in verdi devel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not so much for developing, but can be useful for debugging if you want to run a single daemon worker in the foreground. I would keep it under verdi daemon as it centralizes all daemon code, especially since circus also calls verdi daemon worker to spawn a new worker. It is a bit weird to have the actual daemon call verdi devel run_daemon as a daemon worker.

@decorators.with_dbenv()
def worker():
"""Run a single daemon worker in the current interpreter."""
from aiida.engine.daemon.worker import start_daemon_worker
start_daemon_worker()
8 changes: 0 additions & 8 deletions aiida/cmdline/commands/cmd_devel.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@ def devel_check_undesired_imports():
echo.echo_success('no issues detected')


@verdi_devel.command('run_daemon')
@decorators.with_dbenv()
def devel_run_daemon():
"""Run a daemon instance in the current interpreter."""
from aiida.engine.daemon.runner import start_daemon
start_daemon()


@verdi_devel.command('validate-plugins')
@decorators.with_dbenv()
def devel_validate_plugins():
Expand Down
Loading