From e2c050515d1fd87003bee773d963913184cd2356 Mon Sep 17 00:00:00 2001 From: xds Date: Mon, 16 Feb 2026 00:30:34 +0300 Subject: [PATCH] feat: Limit concurrent image generations to 4 using an asyncio semaphore. --- api/__pycache__/dependency.cpython-313.pyc | Bin 2468 -> 2468 bytes .../GenerationRequest.cpython-313.pyc | Bin 3698 -> 3698 bytes .../generation_service.cpython-313.pyc | Bin 27911 -> 28392 bytes api/service/generation_service.py | 11 ++++++++--- models/__pycache__/Generation.cpython-313.pyc | Bin 3329 -> 3329 bytes repos/__pycache__/dao.cpython-313.pyc | Bin 1466 -> 1466 bytes .../generation_repo.cpython-313.pyc | Bin 7177 -> 7177 bytes 7 files changed, 8 insertions(+), 3 deletions(-) diff --git a/api/__pycache__/dependency.cpython-313.pyc b/api/__pycache__/dependency.cpython-313.pyc index eb067d1ef5835eda4ff5c7e6a03a68aa9bef1acd..ef8b4759d66b2be0c5bfd3391c0201559694674e 100644 GIT binary patch delta 20 acmZ1?yhND$GcPX}0}wDzow$*ECMN(kWCa)i delta 20 acmZ1?yhND$GcPX}0}xzj=-tRYlM?_tZ3WB# diff --git a/api/models/__pycache__/GenerationRequest.cpython-313.pyc b/api/models/__pycache__/GenerationRequest.cpython-313.pyc index 0726ddb09aee4939f0106e13d72247b80b8f7d21..1bfa07a6f1174db96fafcc035ece38a5ddfe66b4 100644 GIT binary patch delta 20 acmew)^GSyLGcPX}0}wDzow$)Zoeuy)-36Hd delta 20 acmew)^GSyLGcPX}0}$N1)VGm4oeuy?IR>r( diff --git a/api/service/__pycache__/generation_service.cpython-313.pyc b/api/service/__pycache__/generation_service.cpython-313.pyc index a0f1879d59e01ba62471ecf76a971f0164da9ec3..5e9d4e94759549e3c70fad6fa93da3ac7670d706 100644 GIT binary patch delta 3649 zcmaJ@4Qx}_6@K?U`#Fgn^6TV5Qvbw`6O$$-e?a&NaUdZ95+J6~ByJqXen}i0JH5{? z6rrYw4d~RhYA#)2E2G_}7N%q;Q3+q%s_RoD~LVAH0dP7__}$~rXdp8If; zcI}+_^SS4od+xdSo}YVAMSuN0TJUjpb{0oJ2bWKU8y|UofrMT?Q&Ej{KCWkwc(xV} zdvhBRC~zFE_2&8Ny!k$ZuU=2b-U6S?Tj;CsnthVD$d{Ss`;5LiUseMTI``4!EndWp z>2QO@m2qBa5$9dl$b(I4wQ&Tw7bSm$B1nHrM;XaQLZ2X6DWw|205m304$@?JL%*DomgF6SPB3*)vRf5Gff$wPjH4@8F*ShI0L>KKdR3>$ zkzxELG6np%!3QrRuNmE_lUy=77cj@ffTGB81v`_1sZc;IM9Q(DWuz&m6Foxq=eR^> zuZ^6_u{JJ-#i{@t6x8eyIV$5oT=vK1-Emw2f=UW*1NH#T_SQy(+)iq+E7yazB%jOm z@zsp)0!1DEyh*%SD5zOMEK?ss{-G!E zAZ54(%ru5TW00IOJGCtY$?wc9$V03}k`eT95FkWW7Zn?q0Xa-TwUd34jaNpJ`-;w> zY?-p$dhJMqWR0}YISL#>+uu%@6{esF6xitkXPoSn%271=J;{jHYF<$GtQk;&rLaUn zHS|2(-QC%}K5f$vl0gb{Hp%UU>ro=Pe9?X+CO{k{=SrIFH9!_naA#=l#DT%)Gp${u zq_m2j-1^csv^)9D(q5rr7ic5ZAny)F5+ON==s5i`P=e6!$E5Of7IC??o)|)sRH^OCb z-I#ux=r_~OJ;;F$vF~u&M!402l^aHOuAe0`ENI{YZ_=}+4s7E|Zet<2XDTHB+-N2> z_BvyJ+NGXCV)quBBE~dho^r}!CN~C6u)_-8Fzb;vh8;=@OuAY>4`&Do6C2w!4r!VE~e_!%lvy@%6G+eSY zoc3O^G+mXNQc~0Z(RcVhHE_0utJeC<*7}=L)2DiEL>Vb-{lD*IaFU(0I;SSzrGD;r zwwut2thIXXENU$mlLDpQSk_u4oU2By72>%X7p12Qjg&oYMXhe#v`q)J6VZ9oVY;Qsx@P>w$FLT72MxSs~j)I$TRiVRdC?IzX=FnGcEAO0202>9($t9Cr1KIoa*#P8s>c zRh?1I6>URz?<`3!uJ~!eSM;QND_%x>$+4B4MXylH>Vil(x|3Gj;AjB*!y(*3?yX!R z-Y>d!tH$(rKUE_qSN-MD*~Y+5L@k&%GZ3Vi1=Cqifb&!JU{QhQ5@*Jl3Og?~FQLf( z2^<>^M`S;1sJM;%ZMAKZ)xr)s8+U;Tqt?^3W((fpB4)X>%d@@>zXlBGn`#EE0miT! zc&rya3xa&V5*|-PptaHEMzE|X82a)2CJlN5HGmIubc6T>5Pu8cMSukWP~qoY?QU|m z*(tKDf0|rx-Xb0ac@?Q!)15xJ18XK6(9P8>MUIC2v|z+zI2+V{K*7CGtMpT3VM`gZ zkyR~A&;~NzQZLqnN&|VdrBO5bI=R`hMQdviimHP=He5h9dvej)~vb#u{Ri7o`oLFft6VyRP!{W zumgCfhGXRJkPFQut-%|7&unO`QZNt=$`QX3574?Ys~lD4-7;JK9cn%OP}>ELu{FVC zwj|j)yb*msjt#$Oh8)&*=>Uqo(p$)rBO{ZoFlINW2WlGyRX_AZTvjl>KAL;sXk2S9 z!ywNCfJ4FfEq6TzBu~-CWQWEFD*zAXm#lt~=ARfnM;h_Xw z%kRg~$M8A;)-+ZC1<;W^FuDtQ9@OWjTD`Y9_#GHdjf`Cy*vUq>Ic@{r!_yxxzn!N! zvVq@0M^ulpf_#Gigwa0IJl0mq?1NSJQmwrH43=Rz@E>w~Y%Tg%@=s$WXlp*WTR~-N zrZ@di!e0knc2q?mUJgU%=I32kGgghqLWzjnjNMd^{&UI|vL-T+FLILgYH{V|;>r_w ZSBk4rTp@WW(wDbGMD6Gw9Q$D>@Lzw{V*mgE delta 3282 zcmZ`*eN0=|6@T~n1A;LaY=|)gjLnx5*k}lJT}Z)TV335Qandwk;u`z{27}pshBT?x zv`Ig-trH`6Te9vm(xxg=yCt$3WlKBdgKlK$6tWK`dTP2&>Z)d%RJwK=iu%Xy?>@eg zZBOv?x#ygB&b{ZHd(Qjt4tYr$G}LzO{C$QjHFty$uSETP&^#wHm$i>d7@WnNsaay9kwHZb$75=ex}jFe-Y}ocgOHX0bS5Yd>rXpxdYF@i zsdec_LuMN%yEQ{JlHjr$%h2Y{LJiOe*uueQ(u}GSKS2M7OvTRKcxVHgv-n6myJsoO z5*sr|R8>i;)SIf#bQnkz^JlwB1MAQ3BzxFv*%fACFTieRm(=^Fqs^ej*#fNE*2xV{+WcgD>VhpK*9d+&6pi$LleAmsir4qR#^cOy zFX698>^n$r>YV)^sp$nj1nA?SWeiY-?;#rQKSaZv;WJR75rIaS-Oel1kI>KL{O0y% zaPPN3_X|xxKVX1^X5eR2*KkUNO%EM}3WTNXjMFWv(bSpzbEGTESw52U)eaN_Kz&T=x6y6&`)R(<=Nz1p;JPo12rrS00& z-QC&Uv1D`k5GyuWfvbbiRK#_Rn3HhO&;DNcNNEj7J1nQ`+fl&~?+dL-7AV@lLq1;A zMkZ3{i}o4FB(u2-EvO>K|33-Itij#F-g9Rfi>2K%yPWAbUb>mc>`Av1+~PqgUFxnZ zm3q^;x_Hv0$S?U(C86(s%)xT3c_f?t)o5pHJsT~yCB0p_;8{sr+*fe9{Y8Cta=^~c zdc3)-t@2>FrCv5)yiN`pn9*Cx?iJhRppkviTPT~l+1I?MvaKt%smZY@+gVn!PL#FC zcbq%XV`^^qcW!G7&;)zAtgH|T(#+9*q*4TGF|yC{OLV>LOOYuqSMPFIxGOy?y=%)q zVVSnf6?e_n-DtShFk3ZO6#S!Y_q=S$X(zW`#kX9wH(j-7?SF99-*VK?IqKhaxK3=H z-a6;$o>gy5UYnd9nse{{ljDhx4N_ji!uxC8?2Yo{M<%#~W8OeDdDY=Bmo5^&*Z5`y zr!IR4XI}Oa(B&BcpW$-t#@1^2iifn6o3D8NGGAORC#_ZHs}&~D8wgjrT3r&zGR;_I zPS02g=qxAb3YnXmse;ao&%o)!TiPSBIQxgUgngm1@QA2#J6+4SBWjt70u=?b63Szc z9tGfDYZm=#hLaI>M85^kL$(}n`T~{-z>5IUL0;n2e^+KBJZWa0if}Bd*;Z~>cr+1J z;`FO{UtB2^$CJ3Q{L$~#A(mBDOP*s*RW4G&da8QOR%<)?w3uD2s!8`r`Mb%&r`4(X zs<-ULqBT9(j^WuA8IOh8H~j_d{l;g=(`;Z%XZ{Z%$co3tMtJub7>ZE7HQK?hY^gQt zx0fw!8MYp_bm(o8w*ogCeDs69eo=<%+Zq|*`~0`xe<=oa)_fGhwS*Q%T! zWaG_cW^o5!WUn;uG=B&3^=!Vmdntec|F{>^P0LV~v1oXFD3MH1E7VSL@D=C{Y>M6T zdq@ep=dUH5Y(q<(c_UQnShS^HH+q`=sAZ=`bXnA>=4Ia~@{-q6#jR&8@?9gF>wajf zC|Q#lSCnx&gZJNtreQQTM&H45rOZXKUII_lv&iRLe92pNGq_W1+m6z_I!>;hypUXA zM|b#0SL(GLf6LhPZO%EohL28#jz!|1rzfCs67V$OyMR{!-vfLf@B{XCkB9u2ec1E4 zesOPp4z3$e3J_)UJ5av`)B?ojUj=moFb#MhJ9@ct!OAp^BT!`4f&rB`i`*a2Sw90DL8 z^a8*@xB+8-A`z!)oTOG}8!jw}LevUq06ek;ZK=TULE>L;%AIQo&P({+e_(EK_~!l* zv6`2pE_s*Ce}eMk^2b>1( JlK2tF`wwQ43OfJ* diff --git a/api/service/generation_service.py b/api/service/generation_service.py index d729d83..d426afa 100644 --- a/api/service/generation_service.py +++ b/api/service/generation_service.py @@ -22,6 +22,9 @@ from adapters.s3_adapter import S3Adapter logger = logging.getLogger(__name__) +# Limit concurrent generations to 4 +generation_semaphore = asyncio.Semaphore(4) + # --- Вспомогательная функция генерации --- async def generate_image_task( @@ -141,10 +144,12 @@ class GenerationService: generation_model.id = gen_id async def runner(gen): - logger.info(f"Starting background generation task for ID: {gen.id}") + logger.info(f"Generation {gen.id} entered queue (waiting for slot)...") try: - await self.create_generation(gen) - logger.info(f"Background generation task finished for ID: {gen.id}") + async with generation_semaphore: + logger.info(f"Starting background generation task for ID: {gen.id}") + await self.create_generation(gen) + logger.info(f"Background generation task finished for ID: {gen.id}") except Exception: # если генерация уже пошла и упала — пометим FAILED try: diff --git a/models/__pycache__/Generation.cpython-313.pyc b/models/__pycache__/Generation.cpython-313.pyc index cb9ecdb2d77fb9c455b1c77b3cb8f4ea7aa01bbf..d93d5e4d3f6a0a0eeec2311933e381102cb21515 100644 GIT binary patch delta 20 acmZpaYLw#s%*)Hg00hiaCvN2a#sdH{>jgjn delta 20 acmZpaYLw#s%*)Hg00i8Z`ZjWZ;{gCPf(3#A diff --git a/repos/__pycache__/dao.cpython-313.pyc b/repos/__pycache__/dao.cpython-313.pyc index 8427c184aabfd89143eb70a632e9aa57c4daf903..a48a4f365b7768ef461611bf98c2e8c3f66fa572 100644 GIT binary patch delta 20 acmdnRy^EXsGcPX}0}wDzow$*EJu3h>umwf{ delta 20 acmdnRy^EXsGcPX}0}yn7?%Bw_o)rK-g9ax6 diff --git a/repos/__pycache__/generation_repo.cpython-313.pyc b/repos/__pycache__/generation_repo.cpython-313.pyc index a36ef065d34ea1a6dbc954970959ccc52b454cbd..34f973c121bd001c21307ede0c4d6deae6617ebf 100644 GIT binary patch delta 20 acmeCQ=(OPe%*)Hg00hiaCvN2aCk+5Nas{IR delta 20 acmeCQ=(OPe%*)Hg00dhV`Zsd_lLi1fhy~sN