def start_daemon(): """Start a daemon runner for the currently configured profile.""" daemon_client = get_daemon_client() configure_logging(daemon=True, daemon_log_file=daemon_client.daemon_log_file) try: manager = get_manager() runner = manager.create_daemon_runner() manager.set_runner(runner) except Exception as exception: LOGGER.exception('daemon runner failed to start') raise def shutdown_daemon(_num, _frame): LOGGER.info('Received signal to shut down the daemon runner') runner.close() signal.signal(signal.SIGINT, shutdown_daemon) signal.signal(signal.SIGTERM, shutdown_daemon) LOGGER.info('Starting a daemon runner') try: runner.start() except SystemError as exception: LOGGER.info('Received a SystemError: %s', exception) runner.close() LOGGER.info('Daemon runner stopped')
def retriever(): configure_logging(daemon=True, daemon_log_file=DAEMON_LOG_FILE) from aiida.daemon.execmanager import retrieve_jobs LOGGER.info('Checking for calculations to retrieve') set_daemon_timestamp(task_name='retriever', when='start') retrieve_jobs() set_daemon_timestamp(task_name='retriever', when='stop')
def start_daemon() -> None: """Start a daemon runner for the currently configured profile.""" daemon_client = get_daemon_client() configure_logging(daemon=True, daemon_log_file=daemon_client.daemon_log_file) try: manager = get_manager() runner = manager.create_daemon_runner() manager.set_runner(runner) except Exception: LOGGER.exception('daemon runner failed to start') raise signals = (signal.SIGTERM, signal.SIGINT) for s in signals: # pylint: disable=invalid-name runner.loop.add_signal_handler(s, lambda s=s: asyncio.create_task(shutdown_runner(runner))) try: LOGGER.info('Starting a daemon runner') runner.start() except SystemError as exception: LOGGER.info('Received a SystemError: %s', exception) runner.close() LOGGER.info('Daemon runner started')
def start_daemon(): """ Start a daemon runner for the currently configured profile """ daemon_client = DaemonClient() configure_logging(daemon=True, daemon_log_file=daemon_client.daemon_log_file) runner = DaemonRunner(rmq_config=get_rmq_config(), rmq_submit=False) def shutdown_daemon(num, frame): logger.info('Received signal to shut down the daemon runner') runner.close() signal.signal(signal.SIGINT, shutdown_daemon) signal.signal(signal.SIGTERM, shutdown_daemon) logger.info('Starting a daemon runner') set_runner(runner) tick_legacy_workflows(runner) try: runner.start() except SystemError as exception: logger.info('Received a SystemError: {}'.format(exception)) runner.close() logger.info('Daemon runner stopped')
def _load_backend(self, schema_check=True): """Load the backend for the currently configured profile and return it. .. note:: this will reconstruct the `Backend` instance in `self._backend` so the preferred method to load the backend is to call `get_backend` which will create it only when not yet instantiated. :param schema_check: force a database schema check if the database environment has not yet been loaded :return: the database backend :rtype: :class:`aiida.orm.implementation.Backend` """ from aiida.backends import BACKEND_DJANGO, BACKEND_SQLA from aiida.common import ConfigurationError, InvalidOperation from aiida.common.log import configure_logging from aiida.manage import configuration profile = self.get_profile() if profile is None: raise ConfigurationError( 'Could not determine the current profile. Consider loading a profile using `aiida.load_profile()`.' ) if configuration.BACKEND_UUID is not None and configuration.BACKEND_UUID != profile.uuid: raise InvalidOperation( 'cannot load backend because backend of another profile is already loaded' ) backend_type = profile.database_backend if backend_type == BACKEND_DJANGO: from aiida.backends.djsite.utils import load_dbenv, _load_dbenv_noschemacheck load_backend = load_dbenv if schema_check else _load_dbenv_noschemacheck elif backend_type == BACKEND_SQLA: from aiida.backends.sqlalchemy.utils import load_dbenv, _load_dbenv_noschemacheck load_backend = load_dbenv if schema_check else _load_dbenv_noschemacheck else: raise ConfigurationError( 'Invalid backend type {} in profile: {}'.format( backend_type, profile.name)) # Do NOT reload the backend environment if already loaded, simply reload the backend instance after if configuration.BACKEND_UUID is None: load_backend(profile) configuration.BACKEND_UUID = profile.uuid # Can only import the backend classes after the backend has been loaded if backend_type == BACKEND_DJANGO: from aiida.orm.implementation.django.backend import DjangoBackend self._backend = DjangoBackend() elif backend_type == BACKEND_SQLA: from aiida.orm.implementation.sqlalchemy.backend import SqlaBackend self._backend = SqlaBackend() # Reconfigure the logging with `with_orm=True` to make sure that profile specific logging configuration options # are taken into account and the `DbLogHandler` is configured. configure_logging(with_orm=True) return self._backend
def reset_log_level(): """Reset the `aiida.common.log.CLI_LOG_LEVEL` global and reconfigure the logging. This fixture should be used by tests that will change the ``CLI_LOG_LEVEL`` global, for example, through the :class:`~aiida.cmdline.params.options.main.VERBOSITY` option in a CLI command invocation. """ from aiida.common import log try: yield finally: log.CLI_LOG_LEVEL = None log.configure_logging()
def override_logging(): """Return a `SandboxFolder`.""" from aiida.common.log import configure_logging config = get_config() try: config.set_option('logging.aiida_loglevel', 'DEBUG') config.set_option('logging.db_loglevel', 'DEBUG') configure_logging(with_orm=True) yield finally: config.unset_option('logging.aiida_loglevel') config.unset_option('logging.db_loglevel') configure_logging(with_orm=True)
def load_profile(profile=None): """Load a profile. .. note:: if a profile is already loaded and no explicit profile is specified, nothing will be done :param profile: the name of the profile to load, by default will use the one marked as default in the config :type profile: str :return: the loaded `Profile` instance :rtype: :class:`~aiida.manage.configuration.Profile` :raises `aiida.common.exceptions.InvalidOperation`: if the backend of another profile has already been loaded """ from aiida.common import InvalidOperation from aiida.common.log import configure_logging global PROFILE global BACKEND_UUID # If a profile is loaded and the specified profile name is None or that of the currently loaded, do nothing if PROFILE and (profile is None or PROFILE.name is profile): return PROFILE profile = get_config().get_profile(profile) if BACKEND_UUID is not None and BACKEND_UUID != profile.uuid: # Once the switching of profiles with different backends becomes possible, the backend has to be reset properly raise InvalidOperation( 'cannot switch profile because backend of another profile is already loaded' ) # Set the global variable and make sure the repository is configured PROFILE = profile PROFILE.configure_repository() # Reconfigure the logging to make sure that profile specific logging configuration options are taken into account. # Note that we do not configure with `with_orm=True` because that will force the backend to be loaded. This should # instead be done lazily in `Manager._load_backend`. configure_logging() return PROFILE
def test_manager(backend=BACKEND_DJANGO, profile_name=None, pgtest=None): """ Context manager for TestManager objects. Sets up temporary AiiDA environment for testing or reuses existing environment, if `AIIDA_TEST_PROFILE` environment variable is set. Example pytest fixture:: def aiida_profile(): with test_manager(backend) as test_mgr: yield fixture_mgr Example unittest test runner:: with test_manager(backend) as test_mgr: # ready for tests # everything cleaned up :param backend: database backend, either BACKEND_SQLA or BACKEND_DJANGO :param profile_name: name of test profile to be used or None (to use temporary profile) :param pgtest: a dictionary of arguments to be passed to PGTest() for starting the postgresql cluster, e.g. {'pg_ctl': '/somepath/pg_ctl'}. Should usually not be necessary. """ from aiida.common.utils import Capturing from aiida.common.log import configure_logging try: if not _GLOBAL_TEST_MANAGER.has_profile_open(): if profile_name: _GLOBAL_TEST_MANAGER.use_profile(profile_name=profile_name) else: with Capturing(): # capture output of AiiDA DB setup _GLOBAL_TEST_MANAGER.use_temporary_profile(backend=backend, pgtest=pgtest) configure_logging(with_orm=True) yield _GLOBAL_TEST_MANAGER finally: _GLOBAL_TEST_MANAGER.destroy_all()
def workflow_stepper(): # daemon for legacy workflow configure_logging(daemon=True, daemon_log_file=DAEMON_LOG_FILE) from aiida.daemon.workflowmanager import execute_steps LOGGER.info('Checking for workflows to manage') # RUDIMENTARY way to check if this task is already running (to avoid acting # again and again on the same workflow steps) try: stepper_is_running = (get_last_daemon_timestamp( 'workflow', when='stop') - get_last_daemon_timestamp( 'workflow', when='start')) <= timedelta(0) except TypeError: # when some timestamps are None (undefined) stepper_is_running = ( get_last_daemon_timestamp('workflow', when='stop') is None and get_last_daemon_timestamp('workflow', when='start') is not None) if not stepper_is_running: set_daemon_timestamp(task_name='workflow', when='start') # the previous wf manager stopped already -> we can run a new one LOGGER.info('running execute_steps') execute_steps() set_daemon_timestamp(task_name='workflow', when='stop') else: LOGGER.info('execute_steps already running')
__copyright__ = ( u'Copyright (c), This file is part of the AiiDA platform. ' u'For further information please visit http://www.aiida.net/. All rights reserved.' ) __license__ = 'MIT license, see LICENSE.txt file.' __version__ = '1.0.1' __authors__ = 'The AiiDA team.' __paper__ = ( u'G. Pizzi, A. Cepellotti, R. Sabatini, N. Marzari, and B. Kozinsky,' u'"AiiDA: automated interactive infrastructure and database for computational science", ' u'Comp. Mat. Sci 111, 218-230 (2016); https://doi.org/10.1016/j.commatsci.2015.09.013 ' u'- http://www.aiida.net.') __paper_short__ = 'G. Pizzi et al., Comp. Mat. Sci 111, 218 (2016).' # Configure the default logging configure_logging() if get_config_option('warnings.showdeprecations'): # If the user does not want to get AiiDA deprecation warnings, we disable them - this can be achieved with:: # verdi config warnings.showdeprecations False # Note that the AiidaDeprecationWarning does NOT inherit from DeprecationWarning warnings.simplefilter('default', AiidaDeprecationWarning) # pylint: disable=no-member # This should default to 'once', i.e. once per different message else: warnings.simplefilter('ignore', AiidaDeprecationWarning) # pylint: disable=no-member if six.PY2: warnings.warn('python 2 will be deprecated in `aiida-core v2.0.0`', DeprecationWarning) # pylint: disable=no-member
def fixture_environment(): """Setup a complete AiiDA test environment, with configuration, profile, database and repository.""" with fixture_manager() as manager: from aiida.common.log import configure_logging configure_logging(with_orm=True) yield manager
def tick_work(): configure_logging(daemon=True, daemon_log_file=DAEMON_LOG_FILE) from aiida.work.daemon import tick_workflow_engine LOGGER.info('Ticking workflows') tick_workflow_engine()