Example #1
0
def create_running_job_exe(agent_id='agent_1', job_type=None, job=None, node=None, timeout=None, input_file_size=10.0,
                           queued=None, started=None, resources=None, priority=None, num_exes=1):
    """Creates a running job execution for unit testing

    :returns: The running job execution
    :rtype: :class:`job.execution.job_exe.RunningJobExecution`
    """

    when = timezone.now()
    if not job:
        job = create_job(job_type=job_type, status='RUNNING', input_file_size=input_file_size, num_exes=num_exes)
    job_type = job.job_type

    # Configuration that occurs at queue time
    input_files = {}
    input_file_ids = job.get_job_data().get_input_file_ids()
    if input_file_ids:
        for input_file in ScaleFile.objects.get_files_for_queued_jobs(input_file_ids):
            input_files[input_file.id] = input_file
    exe_config = QueuedExecutionConfigurator(input_files).configure_queued_job(job)

    job_exe = JobExecution()
    job_exe.set_cluster_id('1234', job.id, job.num_exes)
    job_exe.job = job
    job_exe.job_type = job_type
    job_exe.exe_num = job.num_exes
    if not node:
        node = node_utils.create_node()
    job_exe.node = node
    if not timeout:
        timeout = job.timeout
    job_exe.timeout = timeout
    job_exe.input_file_size = input_file_size
    if not resources:
        resources = job.get_resources()
    job_exe.resources = resources.get_json().get_dict()
    job_exe.configuration = exe_config.get_dict()
    if not queued:
        queued = when
    job_exe.queued = queued
    if not started:
        started = when + datetime.timedelta(seconds=1)
    job_exe.started = started
    job_exe.save()

    if not priority:
        priority = job.priority

    # Configuration that occurs at schedule time
    workspaces = {}
    for workspace in Workspace.objects.all():
        workspaces[workspace.name] = workspace
    secret_config = ScheduledExecutionConfigurator(workspaces).configure_scheduled_job(job_exe, job_type,
                                                                                       job_type.get_job_interface(),'INFO')
    return RunningJobExecution(agent_id, job_exe, job_type, secret_config, priority)
Example #2
0
    def _process_scheduled_job_executions(self, framework_id,
                                          queued_job_executions, job_types,
                                          workspaces):
        """Processes the given queued job executions that have been scheduled and returns the new running job
        executions. All database updates occur in an atomic transaction.

        :param framework_id: The scheduling framework ID
        :type framework_id: string
        :param queued_job_executions: A list of queued job executions that have been scheduled
        :type queued_job_executions: list
        :param job_types: A dict of all job types stored by ID
        :type job_types: dict
        :param workspaces: A dict of all workspaces stored by name
        :type workspaces: dict
        :returns: The running job executions stored in lists by node ID
        :rtype: dict
        """

        started = now()
        running_job_exes = {}
        configurator = ScheduledExecutionConfigurator(workspaces)

        with transaction.atomic():
            # Bulk create the job execution models
            job_exe_models = []
            scheduled_models = {}  # {queue ID: (job_exe model, config)}
            canceled_models = {}  # {queue ID: job_exe model}
            for queued_job_exe in queued_job_executions:
                job_exe_model = queued_job_exe.create_job_exe_model(
                    framework_id, started)
                job_exe_models.append(job_exe_model)
                if queued_job_exe.is_canceled:
                    canceled_models[queued_job_exe.id] = job_exe_model
                else:
                    job_type = job_types[job_exe_model.job_type_id]
                    # The configuration stored in the job_exe model has been censored so it is safe to save in database
                    # The returned configuration may contain secrets and should be passed to running job_exe for use
                    config = configurator.configure_scheduled_job(
                        job_exe_model, job_type, queued_job_exe.interface,
                        scheduler_mgr.config.system_logging_level)
                    scheduled_models[queued_job_exe.id] = (job_exe_model,
                                                           config)
            JobExecution.objects.bulk_create(job_exe_models)

            # Create running and canceled job executions
            queue_ids = []
            canceled_job_exe_end_models = []
            for queued_job_exe in queued_job_executions:
                queue_ids.append(queued_job_exe.id)
                if queued_job_exe.is_canceled:
                    job_exe_model = canceled_models[queued_job_exe.id]
                    canceled_job_exe_end_models.append(
                        job_exe_model.create_canceled_job_exe_end_model(
                            started))
                else:
                    agent_id = queued_job_exe.scheduled_agent_id
                    job_exe_model = scheduled_models[queued_job_exe.id][0]
                    job_type = job_types[job_exe_model.job_type_id]
                    config = scheduled_models[queued_job_exe.id][
                        1]  # May contain secrets!
                    priority = queued_job_exe.priority
                    running_job_exe = RunningJobExecution(
                        agent_id, job_exe_model, job_type, config, priority)
                    if running_job_exe.node_id in running_job_exes:
                        running_job_exes[running_job_exe.node_id].append(
                            running_job_exe)
                    else:
                        running_job_exes[running_job_exe.node_id] = [
                            running_job_exe
                        ]

            # Add canceled job execution end models to manager to be sent to messaging backend
            if canceled_job_exe_end_models:
                job_exe_mgr.add_canceled_job_exes(canceled_job_exe_end_models)

            # Delete queue models
            Queue.objects.filter(id__in=queue_ids).delete()

        duration = now() - started
        msg = 'Queries to process scheduled jobs took %.3f seconds'
        if duration > SCHEDULE_QUERY_WARN_THRESHOLD:
            logger.warning(msg, duration.total_seconds())
        else:
            logger.debug(msg, duration.total_seconds())

        return running_job_exes