Beispiel #1
0
    def wrapper(*args, **kwargs):
        if kwargs.get('check_workers', True):
            try:
                if not workers():
                    return ActionResult(result=False, message='can not find celery workers, please check worker status')
            except exceptions.RabbitMQConnectionError as e:
                return ActionResult(result=False, message='celery worker status check failed with message: %s, '
                                                          'check rabbitmq status please' % e.message)
            except RedisConnectionError:
                return ActionResult(result=False, message='redis connection error, check redis status please')

        return func(*args, **kwargs)
Beispiel #2
0
    def start(self, executor, check_workers=True):
        """
        启动当前流程
        @param executor: 执行者
        @param check_workers: 是否检测 worker 的状态
        @return: 执行结果
        """
        from pipeline.engine import api
        from pipeline.utils.context import get_pipeline_context
        from pipeline.engine.models import FunctionSwitch
        from pipeline.engine.core.api import workers

        if FunctionSwitch.objects.is_frozen():
            return ActionResult(result=False, message='engine has been freeze, try later please')

        if check_workers:
            try:
                if not workers():
                    return ActionResult(result=False, message='can not find celery workers, please check worker status')
            except RabbitMQConnectionError as e:
                return ActionResult(result=False, message='celery worker status check failed with message: %s, '
                                                          'check rabbitmq status please' % e.message)
            except RedisConnectionError:
                return ActionResult(result=False, message='redis connection error, check redis status please')

        with transaction.atomic():
            instance = self.__class__.objects.select_for_update().get(id=self.id)
            if instance.is_started:
                return ActionResult(result=False, message='pipeline instance already started.')
            instance.start_time = timezone.now()
            instance.is_started = True
            instance.executor = executor

            # calculate tree info
            instance.calculate_tree_info()

            pipeline_data = instance.execution_data

            try:
                parser_cls = import_string(settings.PIPELINE_PARSER_CLASS)
            except ImportError:
                return ActionResult(result=False, message='invalid parser class: %s' % settings.PIPELINE_PARSER_CLASS)

            parser = parser_cls(pipeline_data)
            pipeline = parser.parse(get_pipeline_context(instance, 'instance'))

            instance.save()

        return api.start_pipeline(pipeline, check_workers=check_workers)
Beispiel #3
0
    def test_workers(self):

        # throw error
        def throw_conn_error(*args, **kwargs):
            raise ConnectionError()

        with mock.patch('pipeline.engine.core.data.cache_for', throw_conn_error):
            self.assertRaises(ConnectionError, api.workers)

        # cache situation
        def return_worker_list(*args, **kwargs):
            return ['worker-1', 'worker-2']

        with mock.patch('pipeline.engine.core.data.cache_for', return_worker_list):
            worker = api.workers()
            self.assertEqual(worker, return_worker_list())
            current_app.control.ping.assert_not_called()
            data.expire_cache.assert_not_called()

        # no cache
        def return_none(*args, **kwargs):
            return None

        with mock.patch('pipeline.engine.core.data.cache_for', return_none):
            # no workers

            def no_workers(*args, **kwargs):
                return []

            current_app.control.ping.reset_mock()
            data.expire_cache.reset_mock()

            with mock.patch('djcelery.app.current_app.control.ping', no_workers):
                worker = api.workers()
                self.assertEqual(worker, no_workers())
                data.expire_cache.assert_not_called()

            # has workers

            def two_workers(*args, **kwargs):
                return ['w1', 'w2']

            current_app.control.ping.reset_mock()
            data.expire_cache.reset_mock()

            with mock.patch('djcelery.app.current_app.control.ping', two_workers):
                worker = api.workers()
                self.assertEqual(worker, two_workers())
                data.expire_cache.assert_called_with('__pipeline__workers__',
                                                     two_workers(),
                                                     settings.PIPELINE_WORKER_STATUS_CACHE_EXPIRES)

            # raise exception

            def raise_mq_conn_error(*args, **kwargs):
                raise socket.error()

            current_app.control.ping.reset_mock()
            data.expire_cache.reset_mock()

            with mock.patch('djcelery.app.current_app.control.ping', raise_mq_conn_error):
                self.assertRaises(RabbitMQConnectionError, api.workers)
                data.expire_cache.assert_not_called()

            # retry test
            ping_mock = mock.MagicMock(side_effect=[[], two_workers()])

            with mock.patch('djcelery.app.current_app.control.ping', ping_mock):
                worker = api.workers()
                self.assertEqual(worker, two_workers())
                ping_mock.assert_has_calls([
                    mock.call(timeout=1),
                    mock.call(timeout=2)
                ])
                data.expire_cache.assert_called_with('__pipeline__workers__',
                                                     two_workers(),
                                                     settings.PIPELINE_WORKER_STATUS_CACHE_EXPIRES)