Ejemplo n.º 1
0
def test_concurrent_ignore_empty():
    runner = concurrent(ignore_empty=True)
    done, pending = run_in_loop(runner.run())
    assert len(done) == 0
    assert len(pending) == 0

    runner = concurrent()
    done, pending = run_in_loop(runner.run(ignore_empty=True))
    assert len(done) == 0
    assert len(pending) == 0
Ejemplo n.º 2
0
def test_concurrent_single():
    @asyncio.coroutine
    def coro(num):
        return num * 2

    p = concurrent(10)
    p.add(coro, 2)
    assert len(p) == 1
    assert p.__len__() == 1
    assert len(p.pool) == 1

    done, pending = run_in_loop(p.run())

    assert len(done) == 1
    assert len(pending) == 0

    for future in done:
        assert future.result() == 4
Ejemplo n.º 3
0
def test_concurrent_observe_exception():
    start = []
    error = []
    finish = []

    @asyncio.coroutine
    def coro(num):
        if num > 4:
            raise ValueError('invalid number')
        return num * 2

    @asyncio.coroutine
    def on_start(task):
        start.append(task)

    @asyncio.coroutine
    def on_error(task, err):
        error.append(err)

    @asyncio.coroutine
    def on_finish(task, result):
        finish.append(result)

    p = concurrent(1)
    p.on('task.start', on_start)
    p.on('task.error', on_error)
    p.on('task.finish', on_finish)

    p.add(coro, 2)
    p.add(coro, 4)
    p.add(coro, 6)
    assert len(p.pool) == 3

    with pytest.raises(ValueError):
        run_in_loop(p.run(return_exceptions=False))

    # Assert event calls
    assert len(start) == 3
    assert len(error) == 1
    assert len(finish) == 2

    finish.sort()
    assert finish == [4, 8]
Ejemplo n.º 4
0
def test_concurrent_observe():
    start = []
    finish = []

    @asyncio.coroutine
    def coro(num):
        return num * 2

    @asyncio.coroutine
    def on_start(task):
        start.append(task)

    @asyncio.coroutine
    def on_finish(task, result):
        finish.append(result)

    p = concurrent(10)
    p.on('task.start', on_start)
    p.on('task.finish', on_finish)

    p.add(coro, 2)
    p.add(coro, 4)
    p.add(coro, 6)
    assert len(p.pool) == 3

    done, pending = run_in_loop(p.run())
    assert len(done) == 3
    assert len(pending) == 0

    # Assert event calls
    assert len(start) == 3
    assert len(finish) == 3

    results = [future.result() for future in done]
    results.sort()
    assert results == [4, 8, 12]

    finish.sort()
    assert finish == [4, 8, 12]
Ejemplo n.º 5
0
def run_test(limit=3, times=10, timespan=0.1):
    p = concurrent(limit)
    for i in range(times):
        p.add(sleep_coro, timespan)
    return (yield from p.run())
Ejemplo n.º 6
0
def test_concurrent_empty_error():
    with pytest.raises(ValueError):
        run_in_loop(concurrent().run())
Ejemplo n.º 7
0
    async def transition(self, wanted_state: State) -> TransitionResult:
        self.check_transition(wanted_state)
        self._wanted_state = wanted_state

        coro_names: List[str] = [i.name for i in self.__workers]
        coro_results: List[Optional[TransitionResult]] = [
            None for _ in self.__workers
        ]

        def pretty_result(
                result: Union[TransitionResult, Exception, None]) -> str:
            result_names = {
                TransitionResult.DONE:
                Color.YELLOW + "Action performed" + Color.RESET,
                TransitionResult.NOOP: Color.GREEN + "Ok" + Color.RESET,
                TransitionResult.ERROR: Color.RED + "ERROR" + Color.RESET,
                None: "Pending"
            }

            if isinstance(result, Exception):
                return Color.RED + "ERROR! Shutting down" + Color.RESET
            return result_names[result]

        def print_progress_update(
                task: asyncio.Task = None,
                result: Optional[TransitionResult] = None) -> None:
            longest_name_len = max(map(len, coro_names)) + 1
            if not task:
                return
            name = coro_names[task.index]
            print(
                f"{Color.CYAN}{(name + ':').ljust(longest_name_len)}{Color.RESET} {pretty_result(result)}"
            )

        def register_result(
                task: asyncio.Task, result: Union[TransitionResult,
                                                  Exception]) -> None:
            coro_results[task.index] = result
            print_progress_update(task, result)

        message = f"Current state is {self.cur_state}, next step: {wanted_state}"
        print(Color.BROWN + ('-' * len(message)))
        print(message)
        print("Trying to reach next state, waiting for worker rendezvous")
        print("Memory usage:")
        subprocess.Popen(['free', '-h']).wait()
        balloon_stat()
        print(('-' * len(message)) + Color.RESET)
        print_progress_update()

        try:
            concurrent = paco.concurrent(limit=len(self.__workers))
            # noinspection PyTypeChecker
            concurrent.on('task.finish', register_result)
            # noinspection PyTypeChecker
            concurrent.on('task.error', register_result)
            for worker in self.__workers:
                concurrent.add(worker.transition, wanted_state)
            # If we don't retrieve the exception manually, two exceptions are thrown making the error more confusing
            done, pending = await concurrent.run(return_when='FIRST_EXCEPTION',
                                                 return_exceptions=True)
            for task in list(done) + list(pending):
                exc = task.exception() or isinstance(
                    task.result(), Exception) and task.result() or None
                if exc:
                    raise exc
            self._cur_state = wanted_state
        except Exception:
            # If state is JOB, next state will be either LOGCAT or STOP, so let's not die yet
            if wanted_state == State.JOB:
                print(
                    Color.RED +
                    "Error in JOB state. Ignoring error state transition and proceeding to next state"
                )
                traceback.print_exc()
                print(Color.RESET, end="")
                self._cur_state = wanted_state
                return TransitionResult.ERROR

            self._cur_state = State.UNKNOWN
            try:
                await concurrent.cancel()
            except (AttributeError, TypeError):
                pass
            raise
        finally:
            self._wanted_state = None

        return TransitionResult.NOOP