Exemple #1
0
    def test_task_lambda(self):
        def func():
            return 'Sentinel Result'

        t = Task(lambda: func())
        t()
        self.assertTrue(t.done())
        self.assertEqual('Sentinel Result', t.result())
Exemple #2
0
    def test_task_normal_callable(self):
        def func():
            return 'Sentinel Result'

        t = Task(func)
        t()
        self.assertTrue(t.done())
        self.assertEqual('Sentinel Result', t.result())
Exemple #3
0
    def test_task_normal_callable_kwargs(self):
        arg_in = 'Sentinel Arg'

        def func(kwarg=None):
            return kwarg

        t = Task(func, kwargs={'kwarg': arg_in})
        t()
        self.assertEqual('Sentinel Arg', t.result())
Exemple #4
0
    def test_coroutine_args(self):
        arg_in = 'Sentinel Arg'

        async def coro(arg):
            return arg

        t = Task(coro, args=(arg_in, ))
        t()
        self.assertEqual('Sentinel Arg', t.result())
Exemple #5
0
    def test_task_normal_callable_args(self):
        arg_in = 'Sentinel Arg'

        def func(arg):
            return arg

        t = Task(func, args=(arg_in, ))
        t()
        self.assertEqual('Sentinel Arg', t.result())
Exemple #6
0
    def test_coroutine_kwargs(self):
        arg_in = 'Sentinel Arg'

        async def coro(kwarg=None):
            return kwarg

        t = Task(coro, kwargs={'kwarg': arg_in})
        t()
        self.assertEqual('Sentinel Arg', t.result())
Exemple #7
0
    def test_coroutine_exception(self):
        async def coro():
            e = Exception()
            e.sentinel_value = 'Sentinel Exception'
            raise e

        t = Task(coro)
        t()
        self.assertTrue(t.done())
        self.assertEqual('Sentinel Exception', t.exception().sentinel_value)
        self.assertEqual(None, t.result())
Exemple #8
0
    def test_exception(self):
        def func():
            e = Exception()
            e.sentinel_value = 'Sentinel Exception'
            raise e

        t = Task(func)
        t()
        self.assertTrue(t.done())
        self.assertEqual('Sentinel Exception', t.exception().sentinel_value)
        self.assertEqual(None, t.result())
Exemple #9
0
    def test_done_task_done_callback_scheduled(self):
        executor = DummyExecutor()

        t = Task(lambda: None, executor=executor)
        t()
        self.assertTrue(t.done())
        t.add_done_callback('Sentinel Value')
        self.assertEqual(1, len(executor.done_callbacks))
        self.assertEqual('Sentinel Value', executor.done_callbacks[0][0])
        args = executor.done_callbacks[0][1]
        self.assertEqual(1, len(args))
        self.assertEqual(t, args[0])
Exemple #10
0
    def test_done_task_called(self):
        called = False

        def func():
            nonlocal called
            called = True

        t = Task(func)
        t()
        self.assertTrue(called)
        self.assertTrue(t.done())
        called = False
        t()
        self.assertFalse(called)
        self.assertTrue(t.done())
Exemple #11
0
    def create_task(self, callback: Union[Callable, Coroutine], *args, **kwargs) -> Task:
        """
        Add a callback or coroutine to be executed during :meth:`spin` and return a Future.

        Arguments to this function are passed to the callback.

        :param callback: A callback to be run in the executor.
        """
        task = Task(callback, args, kwargs, executor=self)
        with self._tasks_lock:
            self._tasks.append((task, None, None))
            self._guard.trigger()
        # Task inherits from Future
        return task
Exemple #12
0
    def test_coroutine(self):
        called1 = False
        called2 = False

        async def coro():
            nonlocal called1
            nonlocal called2
            called1 = True
            await asyncio.sleep(0)
            called2 = True
            return 'Sentinel Result'

        t = Task(coro)
        t()
        self.assertTrue(called1)
        self.assertFalse(called2)

        called1 = False
        t()
        self.assertFalse(called1)
        self.assertTrue(called2)
        self.assertTrue(t.done())
        self.assertEqual('Sentinel Result', t.result())
Exemple #13
0
    def create_task(self, callback, *args, **kwargs):
        """
        Add a callback or coroutine to be executed during :meth:`spin` and return a Future.

        Arguments to this function are passed to the callback.

        :param callback: A callback to be run in the executor
        :type callback: callable or coroutine function
        :rtype: :class:`rclpy.task.Future` instance
        """
        task = Task(callback, args, kwargs, executor=self)
        with self._tasks_lock:
            self._tasks.append((task, None, None))
        # Task inherits from Future
        return task
Exemple #14
0
    def _make_handler(
        self,
        entity: WaitableEntityType,
        node: 'Node',
        take_from_wait_list: Callable,
        call_coroutine: Coroutine
    ) -> Task:
        """
        Make a handler that performs work on an entity.

        :param entity: An entity to wait on.
        :param node: The node associated with the entity.
        :param take_from_wait_list: Makes the entity to stop appearing in the wait list.
        :param call_coroutine: Does the work the entity is ready for
        """
        # Mark this so it doesn't get added back to the wait list
        entity._executor_event = True

        async def handler(entity, gc, is_shutdown, work_tracker):
            if is_shutdown or not entity.callback_group.beginning_execution(entity):
                # Didn't get the callback, or the executor has been ordered to stop
                entity._executor_event = False
                gc.trigger()
                return
            with work_tracker:
                arg = take_from_wait_list(entity)

                # Signal that this has been 'taken' and can be added back to the wait list
                entity._executor_event = False
                gc.trigger()

                try:
                    await call_coroutine(entity, arg)
                finally:
                    entity.callback_group.ending_execution(entity)
                    # Signal that work has been done so the next callback in a mutually exclusive
                    # callback group can get executed
                    gc.trigger()
        task = Task(
            handler, (entity, self._guard, self._is_shutdown, self._work_tracker),
            executor=self)
        with self._tasks_lock:
            self._tasks.append((task, entity, node))
        return task
Exemple #15
0
    def _make_handler(self, entity, node, take_from_wait_list, call_coroutine):
        """
        Make a handler that performs work on an entity.

        :param entity: An entity to wait on
        :param take_from_wait_list: Makes the entity to stop appearing in the wait list
        :type take_from_wait_list: callable
        :param call_coroutine: Does the work the entity is ready for
        :type call_coroutine: coroutine function
        :rtype: callable
        """
        # Mark this so it doesn't get added back to the wait list
        entity._executor_event = True

        async def handler(entity, gc, is_shutdown, work_tracker):
            if is_shutdown or not entity.callback_group.beginning_execution(
                    entity):
                # Didn't get the callback, or the executor has been ordered to stop
                entity._executor_event = False
                _rclpy.rclpy_trigger_guard_condition(gc)
                return
            with work_tracker:
                arg = take_from_wait_list(entity)

                # Signal that this has been 'taken' and can be added back to the wait list
                entity._executor_event = False
                _rclpy.rclpy_trigger_guard_condition(gc)

                try:
                    await call_coroutine(entity, arg)
                finally:
                    entity.callback_group.ending_execution(entity)
                    # Signal that work has been done so the next callback in a mutually exclusive
                    # callback group can get executed
                    _rclpy.rclpy_trigger_guard_condition(gc)

        task = Task(handler, (entity, self._guard_condition, self._is_shutdown,
                              self._work_tracker),
                    executor=self)
        with self._tasks_lock:
            self._tasks.append((task, entity, node))
        return task
Exemple #16
0
 def test_cancelled(self):
     t = Task(lambda: None)
     t.cancel()
     self.assertTrue(t.cancelled())
Exemple #17
0
 def test_done_task_cancelled(self):
     t = Task(lambda: None)
     t()
     t.cancel()
     self.assertFalse(t.cancelled())
Exemple #18
0
 def test_executing(self):
     t = Task(lambda: None)
     self.assertFalse(t.executing())