From 34569066a9ca97a186839944390a05cf63c7b208 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.dos.anjos@gmail.com> Date: Sun, 8 May 2016 21:53:27 +0200 Subject: [PATCH] [backend] Work-around gevent limitation for Django test server --- beat/web/backend/tests.py | 12 +-- beat/web/backend/utils.py | 55 ------------ beat/web/backend/views.py | 13 +-- beat/web/scripts/worker.py | 5 +- beat/web/settings/settings.py | 10 +++ .../{backend => utils}/environments/default | 0 beat/web/utils/path.py | 89 +++++++++++++++++++ 7 files changed, 112 insertions(+), 72 deletions(-) rename beat/web/{backend => utils}/environments/default (100%) create mode 100644 beat/web/utils/path.py diff --git a/beat/web/backend/tests.py b/beat/web/backend/tests.py index faa4f8424..792619117 100644 --- a/beat/web/backend/tests.py +++ b/beat/web/backend/tests.py @@ -2042,9 +2042,9 @@ class Working(BaseBackendTestCase): from beat.core.async import resolve_cpulimit_path self.cpulimit = resolve_cpulimit_path(None) - from . import utils - self.process = utils.resolve_process_path() - self.environments = utils.find_environments(None) + from ..utils import path + self.process = path.resolve_process_path() + self.environments = path.find_environments(None) self.env1_execute = self.environments['environment (1)']['execute'] if not os.path.exists(settings.CACHE_ROOT): @@ -2497,9 +2497,9 @@ class WorkingExternally(TransactionTestCase): from beat.core.async import resolve_cpulimit_path self.cpulimit = resolve_cpulimit_path(None) - from . import utils - self.process = utils.resolve_process_path() - self.environments = utils.find_environments(None) + from ..utils import path + self.process = path.resolve_process_path() + self.environments = path.find_environments(None) if not os.path.exists(settings.CACHE_ROOT): os.makedirs(settings.CACHE_ROOT) diff --git a/beat/web/backend/utils.py b/beat/web/backend/utils.py index 1ec4deb74..351026f8f 100644 --- a/beat/web/backend/utils.py +++ b/beat/web/backend/utils.py @@ -352,61 +352,6 @@ def cleanup_zombies(): child.wait() -def resolve_process_path(): - '''Returns the path to cpulimit''' - - basedir = os.path.dirname(os.path.realpath(sys.argv[0])) - r = os.path.join(basedir, 'process') - - if not os.path.exists(r): - raise RuntimeError("Cannot find `process.py' at `%s' - please check " \ - "your installation" % basedir) - - return r - - -def find_environments(paths=None): - '''Finds list of known environments - - Parameters: - - paths (list, Optional): A list of paths where to search for environments. - If not set, then load default environments if possible. - - - Returns: - - dict: A dictionary containing each environment available using as key the - natural key for environments (i.e., ``name (version)``) and as values - another dictionary with these keys: - - * name: The environment name (str) - * version: The environment version (str) - * os: The output of ``uname -a`` (list): - 1. Operating system (str) - 2. Hostname (str) - 3. Kernel version (str) - 4. Kernel compilation details (str) - 5. Platform (``x86_64`` for 64-bits or ``i386`` for 32-bits) (str) - * execute: The path to the ``execute`` script to be used for running - user jobs (str) - * directory: The path leading to the root of this environment (str) - - ''' - - from beat.core.execution import discover_environments - - if paths is not None: - logger.debug("Search for environments at `%s'", os.pathsep.join(paths)) - return discover_environments(paths) - - else: - import pkg_resources - path = pkg_resources.resource_filename(__name__, 'environments') - logger.debug("Search for environments at `%s'", path) - return discover_environments([path]) - - def pick_execute(split, environments): """Resolves the path to the ``execute`` program to use for the split""" diff --git a/beat/web/backend/views.py b/beat/web/backend/views.py index 3e5780be2..6d405cad1 100644 --- a/beat/web/backend/views.py +++ b/beat/web/backend/views.py @@ -42,8 +42,6 @@ from django.contrib.auth.decorators import login_required from django.http import HttpResponseForbidden from django.contrib import messages -from beat.core.async import resolve_cpulimit_path - from ..experiments.models import Experiment from .models import Environment, Worker, Queue @@ -58,18 +56,14 @@ from . import schedule class Work: '''Helper to do the required worker job for local scheduling''' - cpulimit = None - process = None - environments = None worker = None def __setup__(self): - Worker.cpulimit = resolve_cpulimit_path(None) - Worker.process = utils.resolve_process_path() - Worker.environments = utils.find_environments(None) Work.worker = Worker.objects.get(name=socket.gethostname()) \ if Worker.objects.count() != 1 else Worker.objects.get() + Work.worker.activate() + Work.worker.save() def __call__(self): @@ -77,7 +71,8 @@ class Work: # Regular work utils.cleanup_zombies() - Work.worker.work(Work.environments, Work.cpulimit, Work.process) + Work.worker.work(settings.WORKER_ENVIRONMENTS, + settings.WORKER_CPULIMIT_PATH, settings.WORKER_PROCESS_PATH) #------------------------------------------------ diff --git a/beat/web/scripts/worker.py b/beat/web/scripts/worker.py index dadc88c2d..aca6f39e9 100644 --- a/beat/web/scripts/worker.py +++ b/beat/web/scripts/worker.py @@ -112,13 +112,14 @@ def main(user_input=None): signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGINT, handler) + from ..utils import path from ..backend import utils from ..backend.models import Worker from beat.core.async import resolve_cpulimit_path cpulimit = resolve_cpulimit_path(arguments['--cpulimit']) - process = utils.resolve_process_path() - environments = utils.find_environments(arguments['--environments']) + process = path.resolve_process_path() + environments = path.find_environments(arguments['--environments']) timing = int(arguments['--period']) \ if arguments['--period'] else settings.WORKER_INTERVAL diff --git a/beat/web/settings/settings.py b/beat/web/settings/settings.py index 357a8efb8..ce05e9550 100644 --- a/beat/web/settings/settings.py +++ b/beat/web/settings/settings.py @@ -251,6 +251,16 @@ WORKER_INTERVAL = 5 #seconds # manually. SCHEDULING_PANEL = True +# If the scheduling panel must be used, we should setup a few things as well +if SCHEDULING_PANEL: + + from ..utils import path + from beat.core.async import resolve_cpulimit_path + WORKER_CPULIMIT_PATH = resolve_cpulimit_path(None) + WORKER_PROCESS_PATH = path.resolve_process_path() + WORKER_ENVIRONMENTS = path.find_environments(None) + + # The maximum index split errors control the maximum number of times we can # incur in an index split error condition without cancelling the block # execution altogether. This number, multiplied by the scheduling interval, diff --git a/beat/web/backend/environments/default b/beat/web/utils/environments/default similarity index 100% rename from beat/web/backend/environments/default rename to beat/web/utils/environments/default diff --git a/beat/web/utils/path.py b/beat/web/utils/path.py new file mode 100644 index 000000000..a95ba5c28 --- /dev/null +++ b/beat/web/utils/path.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : + +############################################################################### +# # +# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ # +# Contact: beat.support@idiap.ch # +# # +# This file is part of the beat.web module of the BEAT platform. # +# # +# Commercial License Usage # +# Licensees holding valid commercial BEAT licenses may use this file in # +# accordance with the terms contained in a written agreement between you # +# and Idiap. For further information contact tto@idiap.ch # +# # +# Alternatively, this file may be used under the terms of the GNU Affero # +# Public License version 3 as published by the Free Software and appearing # +# in the file LICENSE.AGPL included in the packaging of this file. # +# The BEAT platform is distributed in the hope that it will be useful, but # +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # +# or FITNESS FOR A PARTICULAR PURPOSE. # +# # +# You should have received a copy of the GNU Affero Public License along # +# with the BEAT platform. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### + +'''Utilities for path management''' + +import os +import sys +import logging +logger = logging.getLogger(__name__) + +import pkg_resources + +from beat.core.execution import discover_environments + + +def resolve_process_path(): + '''Returns the path to cpulimit''' + + basedir = os.path.dirname(os.path.realpath(sys.argv[0])) + r = os.path.join(basedir, 'process') + + if not os.path.exists(r): + raise RuntimeError("Cannot find `process' at `%s' - please check " \ + "your installation" % basedir) + + return r + + +def find_environments(paths=None): + '''Finds list of known environments + + Parameters: + + paths (list, Optional): A list of paths where to search for environments. + If not set, then load default environments if possible. + + + Returns: + + dict: A dictionary containing each environment available using as key the + natural key for environments (i.e., ``name (version)``) and as values + another dictionary with these keys: + + * name: The environment name (str) + * version: The environment version (str) + * os: The output of ``uname -a`` (list): + 1. Operating system (str) + 2. Hostname (str) + 3. Kernel version (str) + 4. Kernel compilation details (str) + 5. Platform (``x86_64`` for 64-bits or ``i386`` for 32-bits) (str) + * execute: The path to the ``execute`` script to be used for running + user jobs (str) + * directory: The path leading to the root of this environment (str) + + ''' + + if paths is not None: + logger.debug("Search for environments at `%s'", os.pathsep.join(paths)) + return discover_environments(paths) + + else: + path = pkg_resources.resource_filename(__name__, 'environments') + logger.debug("Search for environments at `%s'", path) + return discover_environments([path]) -- GitLab