рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рдореИрдВ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреЗрд╢реЗрд╡рд░ рдмрд░реНрдирдЖрдЙрдЯ рдХреА рдХрд╣рд╛рдиреА рдмрддрд╛рдКрдВрдЧрд╛ред
рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рдореБрдЭреЗ рд░реВрдЯреАрди рдЯреНрд░реЗрдбрдорд┐рд▓ рд╕реЗ рдирдлрд░рдд рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рд╕реЗрд▓реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВред рд╣рд░ рдмрд╛рд░ рдЬрдм рдХреЛрдИ рдХрд╛рд░реНрдп 2 + 2 = 5
рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдорд╛рдзрд╛рди рдЯреЗрдореНрдкрд▓реЗрдЯ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕реНрдЯрд╛рд░реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рд╕реЗрд▓реЗрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ - рдПрдХ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдореИрдВрдиреЗ рдПрдХ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рд╕рдВрдШрд░реНрд╖ рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдЖрдпрд╛ред

рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдмрд┐рдВрджреБ
рдЕрдЬрд╡рд╛рдЗрди рдХреЗ рд╕рд╛рдзрд╛рд░рдг рдХрд╛рд░реНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдПрдХ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕реНрдЯрд╛рд░реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди, рдЬреЛ рдХрдХреНрд╖рд╛ рдХреЛ рддрддреНрдХрд╛рд▓ рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдХрд╛рд░реНрдп рдХреЗ рд╕рднреА рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╣реИ:
class MyTask( FirstMixin, SecondMixin, ThirdMixin, ): def main(self): data = self.do_something() response = self.remote_call(data) parsed = self.parser(response) return self.process(parsed) @app.task(bind=True) def my_task(self, arg1, arg2): instance = MyTask( celery_task=self, arg1=arg1, arg2=arg2, ) return instance.full_task()
рдЙрд╕реА рд╕рдордп, full_task
рдкрджреНрдзрддрд┐ рдореЗрдВ main
рд▓рд┐рдП рдХреЙрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ, рд▓реЙрдЧрд┐рдВрдЧ рдФрд░ рдЕрдиреНрдп рдмрдХрд╡рд╛рд╕ рд╕реЗ рднреА рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ рдЬреЛ рд╕реАрдзреЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИред
рдЯрд╛рд╕реНрдХрдХреНрд▓рд╛рд╕ рд╡рд┐рдЪрд╛рд░
рдЯрд╛рд╕реНрдХрдХреНрд▓рд╛рд╕ рдХреА рдЬрдбрд╝ рдореЗрдВ рдПрдХ рд╕рд░рд▓ рд╡рд┐рдЪрд╛рд░ рдирд┐рд╣рд┐рдд рд╣реИ: рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдореЗрдВ, рдЖрдк task
рдХреНрд▓рд╛рд╕ рдХреА рдПрдХ рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ рд╕реНрдЯрд╛рд░реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╡рд╛рд░рд┐рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
class BaseTask: def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) def full_task(self): try: return self.main() except: self.celery_task.retry(countdown=30) @classmethod def task(cls, task, **kwargs): self = cls( celery_task=celery_task, **kwargs, ) return self.full_task()
рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдПрдХрддреНрд░рд┐рдд рд╕рднреА рд╕рд╣рд╛рдпрдХ рдмреЛрд░рд┐рдпрддред рд╣рдо рдлрд┐рд░ рдЙрд╕рдХреЗ рдкрд╛рд╕ рдирд╣реАрдВ рд▓реМрдЯреЗрдВрдЧреЗред рд╣рдореЗрдВ рдХрд╛рд░реНрдп рдХреЗ рддрд░реНрдХ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рд╣реИ:
@app.taskcls(bind=True) class MyTask( BaseTask, FirstMixin, SecondMixin, ThirdMixin, ): def main(self): data = self.do_something() response = self.remote_call(data) parsed = self.parser(response) return self.process(parsed)
рдЬреНрдпрд╛рджрд╛ рднреВрд╕реА рдирд╣реАрдВ, рдЬреНрдпрд╛рджрд╛ рдмреЗрд╣рддрд░ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
MyTask.task.delay(...)
MyTask.task
рдореЗрдВ рд╕рднреА рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ: delay
, apply_async
рдФрд░, рдЖрдо рддреМрд░ рдкрд░ рдмреЛрд▓рдирд╛, рдпрд╣ рд╣реИред
рдЕрдм рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рддрд░реНрдХред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдореЗрдВ bind = True
рдХреЛ рдбреНрд░реИрдЧ рдХрд░рдирд╛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдордЬреЗрджрд╛рд░ рд╣реИред рдХреНрдпрд╛ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ?
class BaseTask: class MetaTask: bind = True def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) def full_task(self): try: return self.main() except: self.celery_task.retry(countdown=30) @classmethod def task(cls, task, **kwargs): self = cls( celery_task=celery_task, **kwargs, ) return self.full_task()
рдиреЗрд╕реНрдЯреЗрдб MetaTask
рдХреНрд▓рд╛рд╕ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реНрдХ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╕рднреА рдмрд╛рд▓ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдпрд╣ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рднреА рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ:
class BaseHasTimeout(BaseTask): class MetaTask(BaseTask.MetaTask): timeout = 42
@app.taskcls
рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ @app.taskcls
рдЧрдП рддрд░реНрдХ рд╕рд░реНрд╡реЛрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╣реИ:
@app.taskcls(timeout=20) class MyTask( BaseHasTimeout, FirstMixin, SecondMixin, ThirdMixin, ): def main(self): ...
рдирддреАрдЬрддрди, рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рд╕рдордп рд╕реАрдорд╛ 20 рд╣реЛ рдЬрд╛рдПрдЧреАред
рдкрд░реЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ
рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ, рдЕрдХреНрд╕рд░ рджреГрд╢реНрдп рд╕реЗ рдХрд╛рд░реНрдп рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрдЪреНрдЪ рдЖрд╕рдВрдЬрди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рджреГрд╢реНрдп рдФрд░ рдХрд╛рд░реНрдп рд╕рдВрдпреБрдХреНрдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
class BaseViewTask: @classmethod def task(cls, **kwargs):
рд╡реИрд╕реЗ, рдирд╛рдореЛрдВ рдХреА рдЯрдХрд░рд╛рд╣рдЯ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдиреЗрд╕реНрдЯреЗрдб рдХреНрд▓рд╛рд╕ рдХреЛ MetaTask
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, Meta
рдирд╣реАрдВ, рдЬреИрд╕рд╛ рдХрд┐ MetaTask
рдореЗрдВред
рдирд┐рд╖реНрдХрд░реНрд╖
рд╕реЗрд▓реЗрд░реА 4.5 рдореЗрдВ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВрдиреЗ рдПрдХ рдкреИрдХреЗрдЬ рднреА рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдЖрдЬ рдЯрд╛рд╕реНрдХрдХреНрд▓реНрд╕ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВред рдкреИрдХреЗрдЬ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдЖрдк рд╕реЗрд▓реЗрд░реА рдХреЛ рд╕рдВрд╕реНрдХрд░рдг 4.5 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдЗрд╕рдХреЗ рдЖрдпрд╛рдд рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред