예제 #1
0
 def send_task(self, name, args=None, kwargs=None, countdown=None,
               eta=None, task_id=None, producer=None, connection=None,
               router=None, result_cls=None, expires=None,
               publisher=None, link=None, link_error=None,
               add_to_parent=True, reply_to=None, **options):
     task_id = task_id or uuid()
     producer = producer or publisher  # XXX compat
     router = router or self.amqp.router
     conf = self.conf
     if conf.CELERY_ALWAYS_EAGER:  # pragma: no cover
         warnings.warn(AlwaysEagerIgnored(
             'CELERY_ALWAYS_EAGER has no effect on send_task',
         ), stacklevel=2)
     options = router.route(options, name, args, kwargs)
     if connection:
         producer = self.amqp.TaskProducer(connection)
     with self.producer_or_acquire(producer) as P:
         self.backend.on_task_call(P, task_id)
         task_id = P.publish_task(
             name, args, kwargs, countdown=countdown, eta=eta,
             task_id=task_id, expires=expires,
             callbacks=maybe_list(link), errbacks=maybe_list(link_error),
             reply_to=reply_to or self.oid, **options
         )
     result = (result_cls or self.AsyncResult)(task_id)
     if add_to_parent:
         parent = get_current_worker_task()
         if parent:
             parent.add_trail(result)
     return result
예제 #2
0
    def send_task(self,
                  name,
                  args=None,
                  kwargs=None,
                  countdown=None,
                  eta=None,
                  task_id=None,
                  producer=None,
                  connection=None,
                  result_cls=None,
                  expires=None,
                  queues=None,
                  publisher=None,
                  **options):
        producer = producer or publisher  # XXX compat
        if self.conf.CELERY_ALWAYS_EAGER:  # pragma: no cover
            warnings.warn(
                AlwaysEagerIgnored(
                    'CELERY_ALWAYS_EAGER has no effect on send_task'))

        result_cls = result_cls or self.AsyncResult
        router = self.amqp.Router(queues)
        options.setdefault('compression', self.conf.CELERY_MESSAGE_COMPRESSION)
        options = router.route(options, name, args, kwargs)
        with self.producer_or_acquire(producer) as producer:
            return result_cls(
                producer.publish_task(name,
                                      args,
                                      kwargs,
                                      task_id=task_id,
                                      countdown=countdown,
                                      eta=eta,
                                      expires=expires,
                                      **options))
예제 #3
0
    def send_task(self, name, args=None, kwargs=None, countdown=None,
                  eta=None, task_id=None, producer=None, connection=None,
                  router=None, result_cls=None, expires=None,
                  publisher=None, link=None, link_error=None,
                  add_to_parent=True, group_id=None, retries=0, chord=None,
                  reply_to=None, time_limit=None, soft_time_limit=None,
                  root_id=None, parent_id=None, route_name=None,
                  shadow=None, chain=None, **options):
        """Send task by name.

        :param name: Name of task to call (e.g. `"tasks.add"`).
        :keyword result_cls: Specify custom result class. Default is
            using :meth:`AsyncResult`.

        Otherwise supports the same arguments as :meth:`@-Task.apply_async`.

        """
        parent = have_parent = None
        amqp = self.amqp
        task_id = task_id or uuid()
        producer = producer or publisher  # XXX compat
        router = router or amqp.router
        conf = self.conf
        if conf.task_always_eager:  # pragma: no cover
            warnings.warn(AlwaysEagerIgnored(
                'task_always_eager has no effect on send_task',
            ), stacklevel=2)
        options = router.route(options, route_name or name, args, kwargs)

        if root_id is None:
            parent, have_parent = self.current_worker_task, True
            if parent:
                root_id = parent.request.root_id or parent.request.id
        if parent_id is None:
            if not have_parent:
                parent, have_parent = self.current_worker_task, True
            if parent:
                parent_id = parent.request.id

        message = amqp.create_task_message(
            task_id, name, args, kwargs, countdown, eta, group_id,
            expires, retries, chord,
            maybe_list(link), maybe_list(link_error),
            reply_to or self.oid, time_limit, soft_time_limit,
            self.conf.task_send_sent_event,
            root_id, parent_id, shadow, chain,
        )

        if connection:
            producer = amqp.Producer(connection)
        with self.producer_or_acquire(producer) as P:
            self.backend.on_task_call(P, task_id)
            amqp.send_task_message(P, name, message, **options)
        result = (result_cls or self.AsyncResult)(task_id)
        if add_to_parent:
            if not have_parent:
                parent, have_parent = self.current_worker_task, True
            if parent:
                parent.add_trail(result)
        return result
예제 #4
0
    def send_task(self,
                  name,
                  args=None,
                  kwargs=None,
                  countdown=None,
                  eta=None,
                  task_id=None,
                  publisher=None,
                  connection=None,
                  connect_timeout=None,
                  result_cls=None,
                  expires=None,
                  queues=None,
                  **options):
        if self.conf.CELERY_ALWAYS_EAGER:  # pragma: no cover
            warnings.warn(
                AlwaysEagerIgnored(
                    "CELERY_ALWAYS_EAGER has no effect on send_task"))

        router = self.amqp.Router(queues)
        result_cls = result_cls or self.AsyncResult

        options.setdefault("compression", self.conf.CELERY_MESSAGE_COMPRESSION)
        options = router.route(options, name, args, kwargs)
        exchange = options.get("exchange")
        exchange_type = options.get("exchange_type")

        with self.default_connection(connection, connect_timeout) as conn:
            publish = publisher or self.amqp.TaskPublisher(
                conn, exchange=exchange, exchange_type=exchange_type)
            try:
                new_id = publish.delay_task(name,
                                            args,
                                            kwargs,
                                            task_id=task_id,
                                            countdown=countdown,
                                            eta=eta,
                                            expires=expires,
                                            **options)
            finally:
                publisher or publish.close()
            return result_cls(new_id)
예제 #5
0
    def send_task(self,
                  name,
                  args=None,
                  kwargs=None,
                  countdown=None,
                  eta=None,
                  task_id=None,
                  producer=None,
                  connection=None,
                  result_cls=None,
                  expires=None,
                  queues=None,
                  publisher=None,
                  link=None,
                  link_error=None,
                  **options):
        producer = producer or publisher  # XXX compat
        if self.conf.CELERY_ALWAYS_EAGER:  # pragma: no cover
            warnings.warn(
                AlwaysEagerIgnored(
                    'CELERY_ALWAYS_EAGER has no effect on send_task'))

        result_cls = result_cls or self.AsyncResult
        router = self.amqp.Router(queues)
        options.setdefault('compression', self.conf.CELERY_MESSAGE_COMPRESSION)
        options = router.route(options, name, args, kwargs)

        logger_task.info("anan: app-{} starts sending task:{{task_id:{}, task_name:{}}} to router:{}".\
                         format(os.getpid(), task_id, name, router))
        with self.producer_or_acquire(producer) as producer:
            return result_cls(
                producer.publish_task(name,
                                      args,
                                      kwargs,
                                      task_id=task_id,
                                      countdown=countdown,
                                      eta=eta,
                                      callbacks=maybe_list(link),
                                      errbacks=maybe_list(link_error),
                                      expires=expires,
                                      **options))
예제 #6
0
    def send_task(self, name, args=None, kwargs=None, countdown=None,
                  eta=None, task_id=None, producer=None, connection=None,
                  router=None, result_cls=None, expires=None,
                  publisher=None, link=None, link_error=None,
                  add_to_parent=True, group_id=None, retries=0, chord=None,
                  reply_to=None, time_limit=None, soft_time_limit=None,
                  root_id=None, parent_id=None, **options):
        amqp = self.amqp
        task_id = task_id or uuid()
        producer = producer or publisher  # XXX compat
        router = router or amqp.router
        conf = self.conf
        if conf.CELERY_ALWAYS_EAGER:  # pragma: no cover
            warnings.warn(AlwaysEagerIgnored(
                'CELERY_ALWAYS_EAGER has no effect on send_task',
            ), stacklevel=2)
        options = router.route(options, name, args, kwargs)

        message = amqp.create_task_message(
            task_id, name, args, kwargs, countdown, eta, group_id,
            expires, retries, chord,
            maybe_list(link), maybe_list(link_error),
            reply_to or self.oid, time_limit, soft_time_limit,
            self.conf.CELERY_SEND_TASK_SENT_EVENT,
            root_id, parent_id,
        )

        if connection:
            producer = amqp.Producer(connection)
        with self.producer_or_acquire(producer) as P:
            self.backend.on_task_call(P, task_id)
            amqp.send_task_message(P, name, message, **options)
        result = (result_cls or self.AsyncResult)(task_id)
        if add_to_parent:
            parent = get_current_worker_task()
            if parent:
                parent.add_trail(result)
        return result
예제 #7
0
    def send_task(self,
                  name,
                  args=None,
                  kwargs=None,
                  countdown=None,
                  eta=None,
                  task_id=None,
                  producer=None,
                  connection=None,
                  router=None,
                  result_cls=None,
                  expires=None,
                  publisher=None,
                  link=None,
                  link_error=None,
                  add_to_parent=True,
                  group_id=None,
                  retries=0,
                  chord=None,
                  reply_to=None,
                  time_limit=None,
                  soft_time_limit=None,
                  root_id=None,
                  parent_id=None,
                  route_name=None,
                  shadow=None,
                  chain=None,
                  task_type=None,
                  **options):
        """Send task by name.

        Supports the same arguments as :meth:`@-Task.apply_async`.

        Arguments:
            name (str): Name of task to call (e.g., `"tasks.add"`).
            result_cls (AsyncResult): Specify custom result class.
        """
        parent = have_parent = None
        amqp = self.amqp
        task_id = task_id or uuid()
        producer = producer or publisher  # XXX compat
        router = router or amqp.router
        conf = self.conf
        if conf.task_always_eager:  # pragma: no cover
            warnings.warn(AlwaysEagerIgnored(
                'task_always_eager has no effect on send_task', ),
                          stacklevel=2)

        ignored_result = options.pop('ignore_result', False)
        options = router.route(options, route_name or name, args, kwargs,
                               task_type)

        if not root_id or not parent_id:
            parent = self.current_worker_task
            if parent:
                if not root_id:
                    root_id = parent.request.root_id or parent.request.id
                if not parent_id:
                    parent_id = parent.request.id

        message = amqp.create_task_message(
            task_id,
            name,
            args,
            kwargs,
            countdown,
            eta,
            group_id,
            expires,
            retries,
            chord,
            maybe_list(link),
            maybe_list(link_error),
            reply_to or self.oid,
            time_limit,
            soft_time_limit,
            self.conf.task_send_sent_event,
            root_id,
            parent_id,
            shadow,
            chain,
            argsrepr=options.get('argsrepr'),
            kwargsrepr=options.get('kwargsrepr'),
        )

        if connection:
            producer = amqp.Producer(connection, auto_declare=False)

        with self.producer_or_acquire(producer) as P:
            with P.connection._reraise_as_library_errors():
                if not ignored_result:
                    self.backend.on_task_call(P, task_id)
                amqp.send_task_message(P, name, message, **options)
        result = (result_cls or self.AsyncResult)(task_id)
        # We avoid using the constructor since a custom result class
        # can be used, in which case the constructor may still use
        # the old signature.
        result.ignored = ignored_result

        if add_to_parent:
            if not have_parent:
                parent, have_parent = self.current_worker_task, True
            if parent:
                parent.add_trail(result)
        return result
예제 #8
0
    def send_task(self, name, args=None, kwargs=None, countdown=None,
                  eta=None, task_id=None, producer=None, connection=None,
                  router=None, result_cls=None, expires=None,
                  publisher=None, link=None, link_error=None,
                  add_to_parent=True, group_id=None, group_index=None,
                  retries=0, chord=None,
                  reply_to=None, time_limit=None, soft_time_limit=None,
                  root_id=None, parent_id=None, route_name=None,
                  shadow=None, chain=None, task_type=None, **options):
        """Send task by name.

        Supports the same arguments as :meth:`@-Task.apply_async`.

        Arguments:
            name (str): Name of task to call (e.g., `"tasks.add"`).
            result_cls (AsyncResult): Specify custom result class.
        """
        parent = have_parent = None
        amqp = self.amqp
        task_id = task_id or uuid()
        producer = producer or publisher  # XXX compat
        router = router or amqp.router
        conf = self.conf
        if conf.task_always_eager:  # pragma: no cover
            warnings.warn(AlwaysEagerIgnored(
                'task_always_eager has no effect on send_task',
            ), stacklevel=2)

        ignore_result = options.pop('ignore_result', False)
        options = router.route(
            options, route_name or name, args, kwargs, task_type)
        if expires is not None:
            if isinstance(expires, datetime):
                expires_s = (maybe_make_aware(expires) - self.now()).total_seconds()
            else:
                expires_s = expires

            if expires_s < 0:
                logger.warning(
                    f"{task_id} has an expiration date in the past ({-expires_s}s ago).\n"
                    "We assume this is intended and so we have set the "
                    "expiration date to 0 instead.\n"
                    "According to RabbitMQ's documentation:\n"
                    "\"Setting the TTL to 0 causes messages to be expired upon "
                    "reaching a queue unless they can be delivered to a "
                    "consumer immediately.\"\n"
                    "If this was unintended, please check the code which "
                    "published this task."
                )
                expires_s = 0

            options["expiration"] = expires_s

        if not root_id or not parent_id:
            parent = self.current_worker_task
            if parent:
                if not root_id:
                    root_id = parent.request.root_id or parent.request.id
                if not parent_id:
                    parent_id = parent.request.id

                if conf.task_inherit_parent_priority:
                    options.setdefault('priority',
                                       parent.request.delivery_info.get('priority'))

        message = amqp.create_task_message(
            task_id, name, args, kwargs, countdown, eta, group_id, group_index,
            expires, retries, chord,
            maybe_list(link), maybe_list(link_error),
            reply_to or self.thread_oid, time_limit, soft_time_limit,
            self.conf.task_send_sent_event,
            root_id, parent_id, shadow, chain,
            ignore_result=ignore_result,
            argsrepr=options.get('argsrepr'),
            kwargsrepr=options.get('kwargsrepr'),
        )

        if connection:
            producer = amqp.Producer(connection, auto_declare=False)

        with self.producer_or_acquire(producer) as P:
            with P.connection._reraise_as_library_errors():
                if not ignore_result:
                    self.backend.on_task_call(P, task_id)
                amqp.send_task_message(P, name, message, **options)
        result = (result_cls or self.AsyncResult)(task_id)
        # We avoid using the constructor since a custom result class
        # can be used, in which case the constructor may still use
        # the old signature.
        result.ignored = ignore_result

        if add_to_parent:
            if not have_parent:
                parent, have_parent = self.current_worker_task, True
            if parent:
                parent.add_trail(result)
        return result
예제 #9
0
    def send_task(self, name, args=None, kwargs=None, countdown=None,
                  eta=None, task_id=None, producer=None, connection=None,
                  router=None, result_cls=None, expires=None,
                  publisher=None, link=None, link_error=None,
                  add_to_parent=True, group_id=None, retries=0, chord=None,
                  reply_to=None, time_limit=None, soft_time_limit=None,
                  root_id=None, parent_id=None, route_name=None,
                  shadow=None, chain=None, task_type=None, **options):
        """Send task by name.

        Supports the same arguments as :meth:`@-Task.apply_async`.

        Arguments:
            name (str): Name of task to call (e.g., `"tasks.add"`).
            result_cls (~@AsyncResult): Specify custom result class.
        """
        # This is a copy of (the top of) celery.app.base.Celery.send_task
        parent = have_parent = None
        amqp = self.amqp
        task_id = task_id or uuid()
        producer = producer or publisher  # XXX compat
        router = router or amqp.router
        conf = self.conf
        if conf.task_always_eager:  # pragma: no cover
            warnings.warn(AlwaysEagerIgnored(
                'task_always_eager has no effect on send_task',
            ), stacklevel=2)
        options = router.route(
            options, route_name or name, args, kwargs, task_type)

        # if not root_id or not parent_id:
        #     parent = self.current_worker_task
        #     if parent:
        #         if not root_id:
        #             root_id = parent.request.root_id or parent.request.id
        #         if not parent_id:
        #             parent_id = parent.request.id

        message = amqp.create_task_message(
            task_id, name, args, kwargs, countdown, eta, group_id,
            expires, retries, chord,
            maybe_list(link), maybe_list(link_error),
            reply_to or self.app.oid, time_limit, soft_time_limit,
            self.conf.task_send_sent_event,
            root_id, parent_id, shadow, chain,
        )

        # if connection:
        #     producer = amqp.Producer(connection, auto_declare=False)
        # self.backend.on_task_call(P, task_id)

        # with self.producer_or_acquire(producer) as P:
        #     with P.connection._reraise_as_library_errors():
        #         if not ignored_result:
        #             self.backend.on_task_call(P, task_id)
        #         amqp.send_task_message(P, name, message, **options)

        yield self.channel.ensure_connected()
        # TODO Handle deferred returned.
        self.send_task_message(name, message, **options)

        result = defer.Deferred()
        self._sent_tasks[task_id] = result

        # result = (result_cls or self.AsyncResult)(task_id)
        # if add_to_parent:
        #     if not have_parent:
        #         parent, have_parent = self.current_worker_task, True
        #     if parent:
        #         parent.add_trail(result)
        #  return result
        result = yield result
        defer.returnValue(result)