рдПрдХ Django рдЖрд╡реЗрджрди рд╕реЗ asyncio рдФрд░ aiohttp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдИрдореЗрд▓ рднреЗрдЬреЗрдВ

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!

рдореИрдВ Ostrovok.ru рдореЗрдВ рдПрдХ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рд╕реЗрд╡рд╛ рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдФрд░ рд╕рдорд░реНрдерди рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рд╕реЗрд╡рд╛ Python3 рдФрд░ Django рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред рд▓реЗрди-рджреЗрди рдкрддреНрд░, рдзрдХреНрдХрд╛ рдФрд░ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕реЗрд╡рд╛ рдЙрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдХрд░рддреА рд╣реИ рдЬреЛ рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ рдСрдлрд╝рд░ рдХреЗ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдореЗрд▓рд┐рдВрдЧ рдХрд░рддреЗ рд╣реИрдВ (рд╕реНрдкреИрдо рдирд╣реАрдВ! рдореБрдЭ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░реЗрдВ, рд╕рджрд╕реНрдпрддрд╛ рд░рджреНрдж рдХрд░реЗрдВ рд╕рджрд╕реНрдпрддрд╛ рд╕реЗ рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ) рдЙрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕ рдкрд░ рд╕рд╣рдорддрд┐ рджреА рд╣реИред рд╕рдордп рдХреЗ рд╕рд╛рде, рд╕рдХреНрд░рд┐рдп рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЖрдзрд╛рд░ рдПрдХ рдорд┐рд▓рд┐рдпрди рд╕реЗ рдЕрдзрд┐рдХ рдкрддреЗ рддрдХ рдмрдврд╝ рдЧрдпрд╛, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдореЗрд▓ рд╕реЗрд╡рд╛ рддреИрдпрд╛рд░ рдирд╣реАрдВ рдереАред рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдирдП рдкрд╛рдпрдерди рдлреАрдЪрд░реНрд╕ рдиреЗ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдореЗрд▓рд┐рдВрдЧ рдХреЛ рддреЗрдЬ рдХрд░рдиреЗ рдФрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╡ рдмрдирд╛рдпрд╛ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╣рдореЗрдВ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдЬреВрдЭрдирд╛ рдкрдбрд╝рд╛ред



рд╕реНрд░реЛрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдореЗрд▓ рдХреЛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП, рдПрдХ рдХрд╛рд░реНрдп рдПрдХ рдХрддрд╛рд░ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд┐рд╕реЗ 60 рдорд╛рд╕ рд╢реНрд░рдорд┐рдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рд╣рдорд╛рд░реА рдХрддрд╛рд░ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ), рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рддреИрдпрд╛рд░ рдХрд┐рдпрд╛, рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛, рднреЗрдЬрд╛ рдПрдХ рдкрддреНрд░ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП Mailgun рдХреЗ рд▓рд┐рдП рдПрдХ HTTP рдЕрдиреБрд░реЛрдз рдФрд░ рдкрддреНрд░ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдпрд╛ред рд╕рдВрдкреВрд░реНрдг рдореЗрд▓рд┐рдВрдЧ рдореЗрдВ 12 рдШрдВрдЯреЗ рддрдХ рдХрд╛ рд╕рдордп рд▓рдЧрд╛, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рд╕реЗ рд▓рдЧрднрдЧ 0.3 рдЕрдХреНрд╖рд░ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рднреЗрдЬрдиреЗ рдФрд░ рдЫреЛрдЯреЗ рдЕрднрд┐рдпрд╛рдиреЛрдВ рдХреЗ рдореЗрд▓рд┐рдВрдЧ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред



рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдорд╛рдзрд╛рди


рддреНрд╡рд░рд┐рдд рд░реВрдкрд░реЗрдЦрд╛ рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдореЗрд▓рдЧреБрди рдХреЗ рд╕рд╛рде рд╕рдВрдмрдВрдз рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдкрд░ рдЦрд░реНрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЪрдВрдХ рдХрд░рдХреЗ рд╕рдореВрд╣ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рд╢реНрд░рдорд┐рдХреЛрдВ рдиреЗ рдореЗрд▓рдЧреБрди рдХреЗ рд╕рд╛рде рдПрдХ рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛, рдЬрд┐рд╕рд╕реЗ рдореЗрд▓рд┐рдВрдЧ рдХрд╛ рд╕рдордп 9 рдШрдВрдЯреЗ рддрдХ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓реА, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рдФрд╕рддрди 0.5 рдЕрдХреНрд╖рд░ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рднреЗрдЬрд╛ рдЧрдпрд╛ред рдмрд╛рдж рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ рд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдЕрднреА рднреА рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ, рдЬрд┐рд╕рдиреЗ рд╣рдореЗрдВ рдПрд╕рд┐рдВрдХреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ред

рд╕рднреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдПрд╕рд┐рдВрд╕реАрдУ рдЪрдХреНрд░ рдореЗрдВ рдбрд╛рд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЛрдЪрдирд╛ рдерд╛:

  1. Django ORM рдЕрднреА рддрдХ asyncio рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди GIL рдХреЛ рд░рд┐рд▓реАрдЬрд╝ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдореБрдЦреНрдп рд▓реВрдк рдХреЛ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
  2. рдЖрдИрдУрдПрдЪрдЯреАрдЯреАрдкреА рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдкрд╛рдпрдерди рд╕рдВрд╕реНрдХрд░рдг 3.6 рдФрд░ рдЙрдЪреНрдЪрддрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рдордп рдореЗрдВ рдбреЙрдХрдЯрд░ рдЫрд╡рд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдиреЛрд╣реЙрдЯрдк рдФрд░ рдкрд╛рдпрдерди 3.5 рдХреЗ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдкреНрд░рдпреЛрдЧ рд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЗрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рднреЗрдЬрдиреЗ рдХреА рдЧрддрд┐ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдХрдо рд╣реИ, рдФрд░ рдЕрдиреБрдХреНрд░рдорд┐рдХ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рддреБрд▓рдиреАрдп рд╣реИред
  3. рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдПрд╕рд┐рдВрд╕реАрдУ рдХреЛрд░реБрдЯрд┐рди рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рд╕реЗ рд╕рднреА рдореЗрдореЛрд░реА рдХрд╛ рдЦрд░реНрдЪ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдкрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрд╡-рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрдХреНрд░ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ, рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧрдард┐рдд рдкрддреНрд░ рднреЗрдЬрддреЗ рд╣реИрдВред

рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рд╣рдо рдЕрдкрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдХрд░реНрдордЪрд╛рд░реА рдХреЛ рдереНрд░реЗрдбрдкреВрд▓ рдкреИрдЯрд░реНрди рдХреА рд╕рдорд╛рдирддрд╛ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдПрд╕рд┐рдиреЛрд╕рд┐рдпреЛ рдЪрдХреНрд░ рдХреЗ рдЕрдВрджрд░ рдмрдирд╛рдПрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдирд┐рдореНрди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

  • рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ Django ORM рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде asyncio.ThreadPoolExecutor рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдирд┐рд░реНрдорд╛рддрд╛ рдЫреЛрдЯреЗ рдмреИрдЪреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдЕрдзрд┐рдЧреНрд░рд╣рдг рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рдиреНрдЬрд╛ 2 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред

def get_campaign_send_data(ids: Iterable[int]) -> Iterable[Mapping[str, Any]]: """    ,     Django ORM   .""" return [{'id': id} for id in ids] async def mail_campaign_producer(ids: Iterable[int], task_queue: asyncio.Queue) -> None: """           ,    .      ,     ThreadPoolExecutor. """ loop = asyncio.get_event_loop() total = len(ids) for subchunk_start in range(0, total, PRODUCER_SUBCHUNK_SIZE): subchunk_ids = ids[subchunk_start : min(subchunk_start + PRODUCER_SUBCHUNK_SIZE, total)] send_tasks = await loop.run_in_executor(None, get_campaign_send_data, subchunk_ids) for task in send_tasks: await task_queue.put(task) 

  • рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рдХрдИ рд╕реМ рдкреНрд░реЗрд╖рдХ - рдПрд╕рд┐рдВрд╕реАрдУ рдХреЛрд░рдЯрд╛рдЗрди, рдЬреЛ рдПрдХ рдЕрдВрддрд╣реАрди рдЪрдХреНрд░ рдореЗрдВ рдХрд╛рд░реНрдп рдХрддрд╛рд░ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рд░рд┐рдкреЛрд░реНрдЯ рдХрддрд╛рд░ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо (рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛, рдпрд╛ рдЕрдкрд╡рд╛рдж) рдбрд╛рд▓рддреЗ рд╣реИрдВред

 async def send_mail(data: Mapping[str, Any], session: aiohttp.ClientSession) -> Union[Mapping[str, Any], Exception]: """    .""" async with session.post(REQUEST_URL, data=data) as response: if response.status_code != 200: raise Exception return data async def mail_campaign_sender( task_queue: asyncio.Queue, result_queue: asyncio.Queue, session: aiohttp.ClientSession ) -> None: """        .     task_done,    ,   . """ while True: try: task_data = await task_queue.get() result = await send_mail(task_data, session) await result_queue.put(result) except asyncio.CancelledError: #     raise except Exception as exception: #     await result_queue.put(exception) finally: task_queue.task_done() 

  • рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдЬреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХрддрд╛рд░ рд╕реЗ рдбреЗрдЯрд╛ рд╕рдореВрд╣ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рдмрд▓реНрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдПрдХ рдкрддреНрд░ рднреЗрдЬрдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдЬрд╛рдирдХрд╛рд░реА рдбрд╛рд▓рддреЗ рд╣реИрдВред

 def process_campaign_results(results: Iterable[Union[Mapping[str, Any], Exception]]) -> None: """  :         """ pass async def mail_campaign_reporter(task_queue: asyncio.Queue, result_queue: asyncio.Queue) -> None: """          ThreadPoolExecutor,        . """ loop = asyncio.get_event_loop() results_chunk = [] while True: try: results_chunk.append(await result_queue.get()) if len(results_chunk) >= REPORTER_BATCH_SIZE: await loop.run_in_executor(None, process_campaign_results, results_chunk) results_chunk.clear() except asyncio.CancelledError: await loop.run_in_executor(None, process_campaign_results, results_chunk) results_chunk.clear() raise finally: result_queue.task_done() 

  • рдХрд╛рд░реНрдп рдХрддрд╛рд░, рдЬреЛ asyncio.Queue рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рддрддреНрд╡реЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рд╣реИ рддрд╛рдХрд┐ рдирд┐рд░реНрдорд╛рддрд╛ рдЗрд╕реЗ рдУрд╡рд░рдлрд┐рд▓ рди рдХрд░реЗрдВ, рд╕рднреА рдореЗрдореЛрд░реА рдЦрд░реНрдЪ рдХрд░реЗрдВред
  • рд░рд┐рдкреЛрд░реНрдЯ рдХрддрд╛рд░реЛрдВ, рднреА asyncio.Queue рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЕрдзрд┐рдХрддрдо рдЖрдЗрдЯрдо рдХреА рд╕реАрдорд╛ рдХреЗ рд╕рд╛рдеред
  • рдПрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╡рд┐рдзрд┐ рдЬреЛ рдХрддрд╛рд░реЛрдВ, рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЛ рдмрдирд╛рддреА рд╣реИ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рд░реЛрдХрдХрд░ рд╡рд┐рддрд░рдг рдкреВрд░рд╛ рдХрд░рддреА рд╣реИред

 async def send_mail_campaign( recipient_ids: Iterable[int], session: aiohttp.ClientSession, loop: asyncio.AbstractEventLoop = None ) -> None: """       .    ,       . """ executor = ThreadPoolExecutor(max_workers=PRODUCERS_COUNT + 1) loop = loop or asyncio.get_event_loop() loop.set_default_executor(executor) task_queue = asyncio.Queue(maxsize=2 * SENDERS_COUNT, loop=loop) result_queue = asyncio.Queue(maxsize=2 * SENDERS_COUNT, loop=loop) producers = [ asyncio.ensure_future(mail_campaign_producer(recipient_ids, task_queue)) for _ in range(PRODUCERS_COUNT) ] consumers = [ asyncio.ensure_future(mail_campaign_sender(task_queue, result_queue, session)) for _ in range(SENDERS_COUNT) ] reporter = asyncio.ensure_future(mail_campaign_reporter(task_queue, result_queue)) # ,      done, _ = await asyncio.wait(producers) #    ,   await task_queue.join() while consumers: consumers.pop().cancel() #    ,     await result_queue.join() reporter.cancel() 

  • рд╕рдордХрд╛рд▓рд┐рдХ рдХреЛрдб рдЬреЛ рд▓реВрдк рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рддрд░рдг рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред

 async def close_session(future: asyncio.Future, session: aiohttp.ClientSession) -> None: """  ,    .  aiohttp      . """ await asyncio.wait([future]) await asyncio.sleep(0.250) await session.close() def mail_campaign_send_chunk(recipient_ids: Iterable[int]) -> None: """     .   ,  asyncio     . """ loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # Session connector = aiohttp.TCPConnector(limit_per_host=0, limit=0) session = aiohttp.ClientSession( connector=connector, auth=aiohttp.BasicAuth('api', API_KEY), loop=loop, read_timeout=60 ) send_future = asyncio.ensure_future(send_mail_campaign(recipient_ids, session, loop=loop)) cleanup_future = asyncio.ensure_future(close_session(send_future, session)) loop.run_until_complete(asyncio.wait([send_future, cleanup_future])) loop.close() 

рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдПрдХ рд╣реА рдореЗрд▓рд┐рдВрдЧ рд╡реЙрд▓реНрдпреВрдо рдФрд░ 12 рд╢рд╛рдорд┐рд▓ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рдореВрд╣рд┐рдХ рдбрд╛рдХ рднреЗрдЬрдиреЗ рдХрд╛ рд╕рдордп рдПрдХ рдШрдВрдЯреЗ рддрдХ рдХрдо рд╣реЛ рдЧрдпрд╛ рдерд╛ред рдпрд╣реА рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 20-25 рдкрддреНрд░ рднреЗрдЬрддрд╛ рд╣реИ, рдЬреЛ рдореВрд▓ рд╕рдорд╛рдзрд╛рди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 50-80 рдЧреБрдирд╛ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рд╣реИред рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рд╕реНрдореГрддрд┐ рдЦрдкрдд рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрддрд░ рдкрд░ рдмрдирд╛рдП рд░рдЦреА рдЧрдИ рдереА, рдкреНрд░реЛрд╕реЗрд╕рд░ рд▓реЛрдб рдереЛрдбрд╝рд╛ рдмрдврд╝ рдЧрдпрд╛, рдиреЗрдЯрд╡рд░реНрдХ рдЙрдкрдпреЛрдЧ рдХрдИ рдмрд╛рд░ рдмрдврд╝ рдЧрдпрд╛, рдЬреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкреНрд░рднрд╛рд╡ рд╣реИред рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рднреА рд╡реГрджреНрдзрд┐ рд╣реБрдИ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛-рдирд┐рд░реНрдорд╛рддрд╛ рдФрд░ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд╛рд╣, рдЬреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдореБрдлреНрдд рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдЫреЛрдЯреЗ рдореЗрд▓рд┐рдВрдЧ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдмрдХрд┐ рдПрдХ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдЕрднрд┐рдпрд╛рди рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред



рд╕рднреА рд▓рд╛рднреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХрдИ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╣реЛрддреА рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

  1. рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддреЗ рд╕рдордп рд╕рд╛рд╡рдзрд╛рдиреА рдмрд░рддрдиреА рдЪрд╛рд╣рд┐рдПред рдПрдХ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдЕрдкрд╡рд╛рдж рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЕрднрд┐рдпрд╛рди рд╕реНрдерд┐рд░ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
  2. рдЬрдм рднреЗрдЬрдирд╛ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдЙрди рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛рдУрдВ рдкрд░ рд░рд┐рдкреЛрд░реНрдЯ рди рдЦреЛрдПрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЕрдВрдд рддрдХ рдЪрдВрдХ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВред
  3. рдЕрднрд┐рдпрд╛рдиреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдЬрдмрд░рди рд░реЛрдХрдиреЗ рдХрд╛ рддрд░реНрдХ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рддреБрд▓рдирд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреМрди рд╕реЗ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдкрддреНрд░ рднреЗрдЬреЗ рдЧрдП рдереЗ рдФрд░ рдХреМрди рд╕реЗ рдирд╣реАрдВ рдереЗред
  4. рдХреБрдЫ рд╕рдордп рдмрд╛рдж, Mailgun рд╕рдкреЛрд░реНрдЯ рд╕реНрдЯрд╛рдл рдиреЗ рд╣рдорд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд┐рдпрд╛ рдФрд░ рд╣рдореЗрдВ рднреЗрдЬрдиреЗ рдХреА рдЧрддрд┐ рдХреЛ рдзреАрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд▓ рд╕реЗрд╡рд╛рдУрдВ рдиреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдИрдореЗрд▓ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдерд╛ рдпрджрд┐ рдЙрдирдХреЗ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡реГрддреНрддрд┐ рдереНрд░реЗрд╢реЛрд▓реНрдб рдорд╛рди рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛред рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрдо рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред
  5. рдЕрдЧрд░ рдПрд╕реЗрдВрд╕-рдбрд┐рдорд╛рдВрдб рдСрдкрд░реЗрд╢рдВрд╕ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЗрдЯрд░ рднреЗрдЬрдиреЗ рдХреЗ рдХреБрдЫ рдЪрд░рдгреЛрдВ рдореЗрдВ рдПрд╕рд┐рдВрдХреЛ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред Jinja2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЯреЗрдореНрдкреНрд▓реЗрдЯрд┐рдВрдЧ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рд╕рдВрдЪрд╛рд▓рди рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рднреЗрдЬрдиреЗ рдХреА рдЧрддрд┐ рдкрд░ рдХреЛрдИ рдкреНрд░рднрд╛рд╡ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рд╣реИред
  6. рдореЗрд▓рд┐рдВрдЧ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрд╕рд┐рдВрдХреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рддрд░рдг рдХрддрд╛рд░ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЕрдиреБрднрд╡ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛! рдпрджрд┐ рдЖрдкрдХреЗ рдХреЛрдИ рдкреНрд░рд╢реНрди рдпрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИрдВ, рддреЛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдВ!

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


All Articles