Exemplo n.º 1
0
def make_traverse_cases():
    # pytest attempts to look for tests derefing the results, causing trouble
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    e3 = error('err3', 3)
    r4 = result(4, 4)
    ph = placeholder()

    return (
        ([], ([], tuple())),
        (1, (1, (1,))),
        (u'abc', (u'abc', (u'abc',))),
        (r0, (u'r0', (u'r0',))),
        (
            [e1, [e2, e3], (r4, r0), [1, 2, [3]], {r4: ['xyz', ph]}],
            (
                [e1, [e2, e3], [4, u'r0'], [1, 2, [3]], {4: ['xyz', ph]}],
                (e1, e2, e3, 4, u'r0', 1, 2, 3, 4, 'xyz', ph)
            )
        ), (
            [{(r4, tuple()): [r0, (e1, ph), tuple()]}],
            (
                [{(4, tuple()): [u'r0', [e1, ph], []]}],
                (4, u'r0', e1, ph)
            )
        )
    )
Exemplo n.º 2
0
 def test_first_mixed(self):
     from flowy import first
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
Exemplo n.º 3
0
 def test_first_mixed(self):
     from flowy import first
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
Exemplo n.º 4
0
def make_collect_cases():
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    ph = placeholder()

    return (
        (((None, None), 1), (None, None)),
        (((None, None), ph), (None, None)),
        (((None, None), e1), (e1, None)),
        (((None, None), e2), (e2, None)),
        (((e2, None), e1), (e1, None)),
        (((None, None), r0), (None, [r0])),
    )
Exemplo n.º 5
0
def make_err_and_ph_cases():
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    ph = placeholder()

    return (
        (((None, False), 1), (None, False)),
        (((None, False), e1), (e1, False)),
        (((None, False), ph), (None, True)),
        (((e1, False), e2), (e1, False)),
        (((e2, False), e1), (e1, False)),
        (((e1, False), ph), (e1, True)),
    )
Exemplo n.º 6
0
def make_collect_cases():
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    ph = placeholder()

    return (
        (((None, None), 1), (None, None)),
        (((None, None), ph), (None, None)),
        (((None, None), e1), (e1, None)),
        (((None, None), e2), (e2, None)),
        (((e2, None), e1), (e1, None)),
        (((None, None), r0), (None, [r0])),
    )
Exemplo n.º 7
0
def make_err_and_ph_cases():
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    ph = placeholder()

    return (
        (((None, False), 1), (None, False)),
        (((None, False), e1), (e1, False)),
        (((None, False), ph), (None, True)),
        (((e1, False), e2), (e1, False)),
        (((e2, False), e1), (e1, False)),
        (((e1, False), ph), (e1, True)),
    )
Exemplo n.º 8
0
 def test_first_results(self):
     from flowy import first
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     self.assertEquals(first([e, p, r, t]).__factory__, r.__factory__)
Exemplo n.º 9
0
 def test_first_results(self):
     from flowy import first
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     self.assertEquals(first([e, p, r, t]).__factory__, r.__factory__)
Exemplo n.º 10
0
 def test_results(self):
     from flowy import finish_order
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     fo = list(finish_order([e, p, r, t]))
     self.assertEquals(fo[0].__factory__, r.__factory__)
     self.assertEquals(fo[1].__factory__, t.__factory__)
     self.assertEquals(fo[2].__factory__, e.__factory__)
     self.assertEquals(fo[3].__factory__, p.__factory__)
Exemplo n.º 11
0
 def test_results(self):
     from flowy import finish_order
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     fo = list(finish_order([e, p, r, t]))
     self.assertEquals(fo[0].__factory__, r.__factory__)
     self.assertEquals(fo[1].__factory__, t.__factory__)
     self.assertEquals(fo[2].__factory__, e.__factory__)
     self.assertEquals(fo[3].__factory__, p.__factory__)
Exemplo n.º 12
0
 def test_mixed(self):
     from flowy import finish_order
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     fo = list(finish_order([1, e, 2, p, 3, r, t]))
     self.assertEquals(fo[:3], [1, 2, 3])
     self.assertEquals(fo[3].__factory__, r.__factory__)
     self.assertEquals(fo[4].__factory__, t.__factory__)
     self.assertEquals(fo[5].__factory__, e.__factory__)
     self.assertEquals(fo[6].__factory__, p.__factory__)
Exemplo n.º 13
0
 def test_mixed(self):
     from flowy import finish_order
     from flowy.result import result, error, timeout, placeholder
     r = result(1, 1)
     t = timeout(2)
     e = error('err!', 3)
     p = placeholder()
     fo = list(finish_order([1, e, 2, p, 3, r, t]))
     self.assertEquals(fo[:3], [1, 2, 3])
     self.assertEquals(fo[3].__factory__, r.__factory__)
     self.assertEquals(fo[4].__factory__, t.__factory__)
     self.assertEquals(fo[5].__factory__, e.__factory__)
     self.assertEquals(fo[6].__factory__, p.__factory__)
Exemplo n.º 14
0
def make_traverse_cases():
    # pytest attempts to look for tests derefing the results, causing trouble
    from flowy.result import error, placeholder, result

    r0 = result(u'r0', 0)
    e1 = error('err1', 1)
    e2 = error('err2', 2)
    e3 = error('err3', 3)
    r4 = result(4, 4)
    ph = placeholder()

    return (([], ([], tuple())), (1, (1, (1, ))),
            (u'abc', (u'abc', (u'abc', ))), (r0, (u'r0', (u'r0', ))),
            ([e1, [e2, e3], (r4, r0), [1, 2, [3]], {
                r4: ['xyz', ph]
            }], ([e1, [e2, e3], [4, u'r0'], [1, 2, [3]], {
                4: ['xyz', ph]
            }], (e1, e2, e3, 4, u'r0', 1, 2, 3, 4, 'xyz', ph))), ([{
                (r4, tuple()): [r0, (e1, ph), tuple()]
            }], ([{
                (4, tuple()): [u'r0', [e1, ph], []]
            }], (4, u'r0', e1, ph))))
Exemplo n.º 15
0
    def __call__(self, *args, **kwargs):
        """Consult the execution history for results or schedule a new task.

        This is method gets called from the user workflow code.
        When calling it, the task it refers to can be in one of the following
        states: RUNNING, READY, FAILED, TIMEDOUT or NOTSCHEDULED.

        * If the task is RUNNING this returns a Placeholder. The Placeholder
          interrupts the workflow execution if its result is accessed by
          raising a SuspendTask exception.
        * If the task is READY this returns a Result object. Calling the result
          method on this object will just return the final value the task
          produced.
        * If the task is FAILED this returns an Error object. Calling the
          result method on this object will raise a TaskError exception
          containing the error message set by the task.
        * In case of a TIMEOUT this returns an Timeout object. Calling the
          result method on this object will raise TaskTimedout exception, a
          subclass of TaskError.
        * If the task was NOTSCHEDULED yet:
            * If any errors in arguments, propagate the error by returning
              another error.
            * If any placeholders in arguments, don't do anything because there
              are unresolved dependencies.
            * Finally, if all the arguments look OK, schedule it for execution.
        """
        task_exec_history = self.task_exec_history
        call_number = self.call_number
        self.call_number += 1
        r = placeholder()
        for retry_number, delay in enumerate(self.retry):
            if task_exec_history.is_timeout(call_number, retry_number):
                continue
            if task_exec_history.is_running(call_number, retry_number):
                break  # result = Placehloder
            if task_exec_history.has_result(call_number, retry_number):
                value = task_exec_history.result(call_number, retry_number)
                order = task_exec_history.order(call_number, retry_number)
                try:
                    value = self.deserialize_result(value)
                except Exception as e:
                    logger.exception('Error while deserializing the activity result:')
                    self.task_decision.fail(e)
                    break  # result = Placeholder
                r = result(value, order)
                break
            if task_exec_history.is_error(call_number, retry_number):
                err = task_exec_history.error(call_number, retry_number)
                order = task_exec_history.order(call_number, retry_number)
                r = error(err, order)
                break
            traversed_args, (err, placeholders) = traverse_data([args, kwargs])
            if err:
                r = copy_result_proxy(err)
                break
            if placeholders:
                break  # result = Placeholder
            t_args, t_kwargs = traversed_args
            try:
                input_data = self.serialize_input(*t_args, **t_kwargs)
            except Exception as e:
                logger.exception('Error while serializing the task input:')
                self.task_decision.fail(e)
                break  # result = Placeholder
            self.task_decision.schedule(call_number, retry_number, delay, input_data)
            break  # result = Placeholder
        else:
            # No retries left, it must be a timeout
            order = task_exec_history.order(call_number, retry_number)
            r = timeout(order)
        return r
Exemplo n.º 16
0
    def __call__(self, *args, **kwargs):
        """Consult the execution history for results or schedule a new task.

        This is method gets called from the user workflow code.
        When calling it, the task it refers to can be in one of the following
        states: RUNNING, READY, FAILED, TIMEDOUT or NOTSCHEDULED.

        * If the task is RUNNING this returns a Placeholder. The Placeholder
          interrupts the workflow execution if its result is accessed by
          raising a SuspendTask exception.
        * If the task is READY this returns a Result object. Calling the result
          method on this object will just return the final value the task
          produced.
        * If the task is FAILED this returns an Error object. Calling the
          result method on this object will raise a TaskError exception
          containing the error message set by the task.
        * In case of a TIMEOUT this returns an Timeout object. Calling the
          result method on this object will raise TaskTimedout exception, a
          subclass of TaskError.
        * If the task was NOTSCHEDULED yet:
            * If any errors in arguments, propagate the error by returning
              another error.
            * If any placeholders in arguments, don't do anything because there
              are unresolved dependencies.
            * Finally, if all the arguments look OK, schedule it for execution.
        """
        task_exec_history = self.task_exec_history
        call_number = self.call_number
        self.call_number += 1
        r = placeholder()
        for retry_number, delay in enumerate(self.retry):
            if task_exec_history.is_timeout(call_number, retry_number):
                continue
            if task_exec_history.is_running(call_number, retry_number):
                break  # result = Placehloder
            if task_exec_history.has_result(call_number, retry_number):
                value = task_exec_history.result(call_number, retry_number)
                order = task_exec_history.order(call_number, retry_number)
                try:
                    value = self.deserialize_result(value)
                except Exception as e:
                    logger.exception(
                        'Error while deserializing the activity result:')
                    self.task_decision.fail(e)
                    break  # result = Placeholder
                r = result(value, order)
                break
            if task_exec_history.is_error(call_number, retry_number):
                err = task_exec_history.error(call_number, retry_number)
                order = task_exec_history.order(call_number, retry_number)
                r = error(err, order)
                break
            traversed_args, (err, placeholders) = traverse_data([args, kwargs])
            if err:
                r = copy_result_proxy(err)
                break
            if placeholders:
                break  # result = Placeholder
            t_args, t_kwargs = traversed_args
            try:
                input_data = self.serialize_input(*t_args, **t_kwargs)
            except Exception as e:
                logger.exception('Error while serializing the task input:')
                self.task_decision.fail(e)
                break  # result = Placeholder
            self.task_decision.schedule(call_number, retry_number, delay,
                                        input_data)
            break  # result = Placeholder
        else:
            # No retries left, it must be a timeout
            order = task_exec_history.order(call_number, retry_number)
            r = timeout(order)
        return r