рдЕрдЬрд╡рд╛рдЗрди рдЯрд╛рд╕реНрдХрдХреНрд▓реНрд╕: рдирдпрд╛ рдбреЗрдХреЛрд░реЗрдЯрд░, рдирдИ рд╕реБрд╡рд┐рдзрд╛рдПрдБ

рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рдореИрдВ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреЗрд╢реЗрд╡рд░ рдмрд░реНрдирдЖрдЙрдЯ рдХреА рдХрд╣рд╛рдиреА рдмрддрд╛рдКрдВрдЧрд╛ред


рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рдореБрдЭреЗ рд░реВрдЯреАрди рдЯреНрд░реЗрдбрдорд┐рд▓ рд╕реЗ рдирдлрд░рдд рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рд╕реЗрд▓реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╣реИрдВред рд╣рд░ рдмрд╛рд░ рдЬрдм рдХреЛрдИ рдХрд╛рд░реНрдп 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): # Somehow init View class manually self = cls(...) return self.celery() @app.taskcls class MyView( BaseViewTask, FirstMixin, SecondMixin, ThirdMixin, APIView, ): queryset = MyModel.objects.all() def get_some_data(self, *args, **kwargs): # common methed return self.queryset.filtert(...) def get(self, request): data = self.get_some_data(request.field) # used in request handling return Response(json.dumps(data)) def post(self, request): self.task.delay(...) return Response(status=201) def celery(self): data = self.get_some_data(...) # also used in background task return self.do_something(data) 

рд╡реИрд╕реЗ, рдирд╛рдореЛрдВ рдХреА рдЯрдХрд░рд╛рд╣рдЯ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдиреЗрд╕реНрдЯреЗрдб рдХреНрд▓рд╛рд╕ рдХреЛ MetaTask рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, Meta рдирд╣реАрдВ, рдЬреИрд╕рд╛ рдХрд┐ MetaTask рдореЗрдВред


рдирд┐рд╖реНрдХрд░реНрд╖


рд╕реЗрд▓реЗрд░реА 4.5 рдореЗрдВ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВрдиреЗ рдПрдХ рдкреИрдХреЗрдЬ рднреА рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдЖрдЬ рдЯрд╛рд╕реНрдХрдХреНрд▓реНрд╕ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВред рдкреИрдХреЗрдЬ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдЖрдк рд╕реЗрд▓реЗрд░реА рдХреЛ рд╕рдВрд╕реНрдХрд░рдг 4.5 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдЗрд╕рдХреЗ рдЖрдпрд╛рдд рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/hi470547/


All Articles