예제 #1
0
    def add_onetime_job(self,
                        func: Union[str, FunctionType],
                        when: Optional[int] = None,
                        scheduled_by: Optional[str] = None,
                        **kwargs) -> int:
        """Schedule a job to run at a later time.

        Args:
            func: The function to call
            when: Optional number of seconds to wait before starting job
            **kwargs: Arguments to pass through to called function
        Returns:
            int: job_id
        """
        if when and isinstance(when, int):
            trigger = 'date'
            run_date = datetime.datetime.utcnow() + datetime.timedelta(
                seconds=when)
        else:
            trigger = None
            run_date = None

        with sqla_session() as session:
            job = Job()
            if run_date:
                job.scheduled_time = run_date
            session.add(job)
            session.flush()
            job_id = job.id

        kwargs['job_id'] = job_id
        kwargs['scheduled_by'] = scheduled_by
        if self.use_mule:
            try:
                import uwsgi
            except Exception as e:
                logger.exception("use_mule is set but not running in uwsgi")
                raise e
            args = dict(kwargs)
            if isinstance(func, FunctionType):
                args['func'] = str(func.__qualname__)
            else:
                args['func'] = str(func)
            args['trigger'] = trigger
            args['when'] = when
            args['id'] = str(job_id)
            uwsgi.mule_msg(json.dumps(args))
            return job_id
        else:
            self._scheduler.add_job(func,
                                    trigger=trigger,
                                    kwargs=kwargs,
                                    id=str(job_id),
                                    run_date=run_date)
            return job_id
예제 #2
0
    def add_onetime_job(self,
                        func: Union[str, FunctionType],
                        when: Optional[int] = None,
                        scheduled_by: Optional[str] = None,
                        **kwargs) -> int:
        """Schedule a job to run at a later time on the mule worker or
        local scheduler depending on setup.

        Some extra checks against kwargs are performed here. If kwarg
        with name 'dry_run' is included, (dry_run) is appended to function
        name. If kwarg job_comment or job_ticket_ref are included, those
        fields in the job will be populated.

        Args:
            func: The function to call
            when: Optional number of seconds to wait before starting job
            scheduled_by: Username that scheduled the job
            **kwargs: Arguments to pass through to called function
        Returns:
            int: job_id
        """
        if when and isinstance(when, int):
            trigger = 'date'
            run_date = datetime.datetime.utcnow() + datetime.timedelta(
                seconds=when)
        else:
            trigger = None
            run_date = None

        if isinstance(func, FunctionType):
            func_qualname = str(func.__qualname__)
        else:
            func_qualname = str(func)
        func_name = func_qualname.split(':')[-1]

        try:
            json.dumps(kwargs)
        except TypeError as e:
            raise TypeError("Job args must be JSON serializable: {}".format(e))

        # Append (dry_run) to function name if set, so we can distinguish dry_run jobs
        try:
            if kwargs['kwargs']['dry_run']:
                func_name += " (dry_run)"
        except Exception:
            pass

        with sqla_session() as session:
            job = Job()
            if run_date:
                job.scheduled_time = run_date
            job.function_name = func_name
            if scheduled_by is None:
                scheduled_by = 'unknown'
            job.scheduled_by = scheduled_by
            job_comment = kwargs['kwargs'].pop('job_comment', None)
            if job_comment and isinstance(job_comment, str):
                job.comment = job_comment[:255]
            job_ticket_ref = kwargs['kwargs'].pop('job_ticket_ref', None)
            if job_ticket_ref and isinstance(job_comment, str):
                job.ticket_ref = job_ticket_ref[:32]
            job.start_arguments = kwargs['kwargs']
            session.add(job)
            session.flush()
            job_id = job.id

        kwargs['job_id'] = job_id
        kwargs['scheduled_by'] = scheduled_by
        if self.use_mule:
            try:
                import uwsgi
            except Exception as e:
                logger.exception("use_mule is set but not running in uwsgi")
                raise e
            args = dict(kwargs)
            args['func'] = func_qualname
            args['trigger'] = trigger
            args['when'] = when
            args['id'] = str(job_id)
            uwsgi.mule_msg(json.dumps(args))
            return job_id
        else:
            self.add_local_job(func,
                               trigger=trigger,
                               kwargs=kwargs,
                               id=str(job_id),
                               run_date=run_date,
                               name=func_qualname)
            return job_id