Celery Beat: Limit to single task instance at a time

后端 未结 5 1780
不思量自难忘°
不思量自难忘° 2020-12-31 17:30

I have celery beat and celery (four workers) to do some processing steps in bulk. One of those tasks is roughly along the lines of, \"for each X that hasn\'t had a Y created

5条回答
  •  一向
    一向 (楼主)
    2020-12-31 18:02

    from functools import wraps
    from celery import shared_task
    
    
    def skip_if_running(f):
        task_name = f'{f.__module__}.{f.__name__}'
    
        @wraps(f)
        def wrapped(self, *args, **kwargs):
            workers = self.app.control.inspect().active()
    
            for worker, tasks in workers.items():
                for task in tasks:
                    if (task_name == task['name'] and
                            tuple(args) == tuple(task['args']) and
                            kwargs == task['kwargs'] and
                            self.request.id != task['id']):
                        print(f'task {task_name} ({args}, {kwargs}) is running on {worker}, skipping')
    
                        return None
    
            return f(self, *args, **kwargs)
    
        return wrapped
    
    
    @shared_task(bind=True)
    @skip_if_running
    def test_single_task(self):
        pass
    
    
    test_single_task.delay()
    

提交回复
热议问题