示例#1
0
    def check(self,
              task,                # Task to check
              classifiers,         # List of the classifiers
              check_schedule=True  # Keep/disregard time-related limits
              ):

        """Determine if a task can be run, return true/false, a list of lists
        (see below) and a string of diagnostics.

        The list of lists contains one list per application passed,
        with that list containing descriptions of the limits passed
        for that application.  (See the code in the top-level limit
        processor to see how this is used.)
        """

        diags = []
        pass_count = 0
        limits_passed = []

        # Run through each application, stopping when one passes or a
        # failed one has stop-on-failure

        for application in self.applications:

            # See if the classifier applies

            try:
                classifier = application['classifier']
                if classifier not in classifiers:
                    continue
            except KeyError:
                # No classifier always applies
                pass

            # Description
            diags.append("Application: %s" % 
                         application.get('description', "(No description)"))

            passed, forced_stop, check_limits_passed, app_diags \
                = self.__check_application(application, task, classifiers,
                                           check_schedule)
           
            diags.extend([ indent(diag) for diag in app_diags])

            if not passed and forced_stop:
                diags.append("    Failed - Stop Forced")
                return False, [], '\n'.join(diags)


            if passed:
                limits_passed.append(check_limits_passed)
                pass_count += 1


        if pass_count > 0:
            return True, limits_passed, '\n'.join(diags)
        else:
            return False, [], '\n'.join(diags)
示例#2
0
    def process(self, task, hints, rewrite=True, prioritize=False):
        """Evaluate a proposed task against the full limit set.

        If the task has no 'run_schedule' section it will be assumed that
        is being evaluated on all other parameters except when it
        runs.  (This will be used for restricting submission of new
        tasks.)

        Arguments:
            task - The proposed task, with run_schedule if there's a run time
            hints - A hash of the hints to be used in identification
            rewrite - True if the rewriter should be applied
            prioritize - True to prioritize the task

        Returns a tuple containing:
            passed - True if the proposed task passed the limits applied
            limits - A list of the limits that passed
            diags - A textual summary of how the conclusion was reached
            task - The task, after rewriting or None if unchanged
            priority - Integer priority or None of not calculated
        """

        if self.inert:
            return True, [], "No limits were applied", None, None

        # TODO: Should this be JSON, or is text sufficient?
        diags = []

        if hints is not None and len(hints) > 0:
            diags.append("Hints:")
            diags.extend([
                pscheduler.indent("%s: %s" % (item, str(hints[item])))
                for item in sorted(hints)
            ])

        # Everything we know about what's being proposed
        proposal = {
            "hints": hints,
            "task": task,
        }

        #
        # Identification
        #

        identifications = self.identifiers.identities(hints)
        if not identifications:
            diags.append("Made no identifications.")
            return False, [], '\n'.join(diags), None, None
        diags.append("Identified as %s" % (', '.join(identifications)))

        #
        # Classification
        #

        classifications = self.classifiers.classifications(identifications)
        if not classifications:
            diags.append("Made no classifications.")
            return False, [], '\n'.join(diags), None, None
        diags.append("Classified as %s" % (', '.join(classifications)))

        check_schedule='run_schedule' in task

        re_new_task = None

        #
        # Rewriting
        #

        if self.rewriter is not None and rewrite:

            try:
                re_changed, re_new_task, re_diags \
                    = self.rewriter(proposal, classifications)
            except Exception as ex:
                return False, [], "Error while rewriting: %s" % (str(ex)), None, None

            if re_changed:
                diags.append("Rewriter made changes:")
                if len(re_diags):
                    diags += map(lambda s: "  " + s, re_diags)
                else:
                    diags.append("  (Not enumerated)")
                task = re_new_task


        #
        # Applications
        #

        passed, app_limits_passed, app_diags \
            = self.applications.check(proposal, classifications, check_schedule)

        diags.append(app_diags)
        diags.append("Proposal %s limits" % ("meets" if passed else "does not meet"))

        # If any of the passed applications had no task limits, there
        # should be no limits placed on the run.

        unlimited = len(app_limits_passed) == 0 \
                    or min([ len(item) for item in app_limits_passed ]) == 0


        #
        # Priorities
        #

        if prioritize and passed and self.prioritizer is not None:
            try:
                priority, pri_diags = self.prioritizer(task, classifications)
            except Exception as ex:
                return False, [], "Error determining priority: %s" % (str(ex)), None, None

            if priority is None:
                return False, [], "Prioritizer produced no result", None, None

            requested_priority = task.get("priority", None)
            if requested_priority is not None:
                requested_message = " %d requested," % (requested_priority)
            else:
                requested_message =""

            diags.append("Priority%s set at %d%s" % (
                requested_message, priority, ":" if len(pri_diags) else "."))
            if len(pri_diags):
                diags += map(lambda s: "  " + s, pri_diags)
        else:
            priority = 0
            diags.append("Priority set to default of %d" % (priority))



        return passed, \
            [] if (unlimited or not passed) else app_limits_passed, \
            '\n'.join(diags), \
            re_new_task, \
            priority
示例#3
0
    def process(self, task, hints, rewrite=True):
        """Evaluate a proposed task against the full limit set.

        If the task has no 'schedule' section it will be assumed that
        is being evaluated on all other parameters except when it
        runs.  (This will be used for restricting submission of new
        tasks.)

        Arguments:
            task - The proposed task
            hints - A hash of the hints to be used in identification
            rewrite - True if the rewriter should be applied

        Returns a tuple containing:
            passed - True if the proposed task passed the limits applied
            limits - A list of the limits that passed
            diags - A textual summary of how the conclusion was reached
            task - The task, after rewriting or None if unchanged
        """

        if self.inert:
            return True, [], "No limits were applied", None

        # TODO: Should this be JSON, or is text sufficient?
        diags = []

        if hints is not None and len(hints) > 0:
            diags.append("Hints:")
            diags.extend([
                pscheduler.indent("%s: %s" % (item, str(hints[item])))
                for item in sorted(hints)
            ])

        identifications = self.identifiers.identities(hints)
        if not identifications:
            diags.append("Made no identifications.")
            return False, [], '\n'.join(diags), None
        diags.append("Identified as %s" % (', '.join(identifications)))

        classifications = self.classifiers.classifications(identifications)
        if not classifications:
            diags.append("Made no classifications.")
            return False, [], '\n'.join(diags), None
        diags.append("Classified as %s" % (', '.join(classifications)))

        check_schedule = 'schedule' in task

        re_new_task = None

        if self.rewriter is not None and rewrite:

            try:
                re_changed, re_new_task, re_diags \
                    = self.rewriter(task, classifications)
            except pscheduler.JQRuntimeError as ex:
                return False, [], "Error while rewriting: %s" % (str(ex)), None

            if re_changed:
                diags.append("Rewriter made changes:")
                if len(re_diags):
                    diags += map(lambda s: "  " + s, re_diags)
                else:
                    diags.append("  (Not enumerated)")
                task = re_new_task

        passed, app_limits_passed, app_diags \
            = self.applications.check(task["test"], classifications, check_schedule)

        diags.append(app_diags)
        diags.append("Proposal %s limits" %
                     ("meets" if passed else "does not meet"))

        # If any of the passed applications had no task limits, there
        # should be no limits placed on the run.

        unlimited = len(app_limits_passed) == 0 \
                    or min([ len(item) for item in app_limits_passed ]) == 0


        return passed, \
            [] if (unlimited or not passed) else app_limits_passed, \
            '\n'.join(diags), \
            re_new_task