From 5238a083094b9e8aa83ab9dc64b72c3cbb7437cc Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 26 May 2026 13:18:47 +0800 Subject: [PATCH] perf: log system - keep file handle open + async queue writes - Replace open/write/flush/close per log call with persistent file handle - Use threading.Queue + background daemon thread for non-blocking writes - Only flush on exception/critical levels or periodically (every 1s idle) - Queue full protection: drop oldest entry instead of blocking event loop - Eliminates disk I/O blocking on slow storage (NFS/cloud disk) during high traffic --- appPublic/README.md | 58 ++++ .../__pycache__/Singleton.cpython-310.pyc | Bin 0 -> 1908 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 188 bytes appPublic/__pycache__/aes.cpython-310.pyc | Bin 0 -> 2218 bytes .../__pycache__/argsConvert.cpython-310.pyc | Bin 0 -> 5915 bytes .../base64_to_file.cpython-310.pyc | Bin 0 -> 2087 bytes .../__pycache__/dictObject.cpython-310.pyc | Bin 0 -> 3339 bytes .../event_dispatcher.cpython-310.pyc | Bin 0 -> 3931 bytes .../__pycache__/folderUtils.cpython-310.pyc | Bin 0 -> 4510 bytes .../__pycache__/jsonConfig.cpython-310.pyc | Bin 0 -> 2060 bytes appPublic/__pycache__/log.cpython-310.pyc | Bin 0 -> 2947 bytes .../__pycache__/myImport.cpython-310.pyc | Bin 0 -> 386 bytes appPublic/__pycache__/myTE.cpython-310.pyc | Bin 0 -> 4437 bytes appPublic/__pycache__/myjson.cpython-310.pyc | Bin 0 -> 648 bytes .../__pycache__/objectAction.cpython-310.pyc | Bin 0 -> 2014 bytes appPublic/__pycache__/rc4.cpython-310.pyc | Bin 0 -> 6030 bytes .../registerfunction.cpython-310.pyc | Bin 0 -> 4172 bytes .../streamhttpclient.cpython-310.pyc | Bin 0 -> 5919 bytes .../__pycache__/timeUtils.cpython-310.pyc | Bin 0 -> 8018 bytes .../__pycache__/unicoding.cpython-310.pyc | Bin 0 -> 1118 bytes .../__pycache__/uniqueID.cpython-310.pyc | Bin 0 -> 1067 bytes appPublic/__pycache__/version.cpython-310.pyc | Bin 0 -> 165 bytes appPublic/__pycache__/worker.cpython-310.pyc | Bin 0 -> 4390 bytes appPublic/k | 289 ++++++++++++++++++ appPublic/log.py | 87 ++++-- 25 files changed, 410 insertions(+), 24 deletions(-) create mode 100644 appPublic/README.md create mode 100644 appPublic/__pycache__/Singleton.cpython-310.pyc create mode 100644 appPublic/__pycache__/__init__.cpython-310.pyc create mode 100644 appPublic/__pycache__/aes.cpython-310.pyc create mode 100644 appPublic/__pycache__/argsConvert.cpython-310.pyc create mode 100644 appPublic/__pycache__/base64_to_file.cpython-310.pyc create mode 100644 appPublic/__pycache__/dictObject.cpython-310.pyc create mode 100644 appPublic/__pycache__/event_dispatcher.cpython-310.pyc create mode 100644 appPublic/__pycache__/folderUtils.cpython-310.pyc create mode 100644 appPublic/__pycache__/jsonConfig.cpython-310.pyc create mode 100644 appPublic/__pycache__/log.cpython-310.pyc create mode 100644 appPublic/__pycache__/myImport.cpython-310.pyc create mode 100644 appPublic/__pycache__/myTE.cpython-310.pyc create mode 100644 appPublic/__pycache__/myjson.cpython-310.pyc create mode 100644 appPublic/__pycache__/objectAction.cpython-310.pyc create mode 100644 appPublic/__pycache__/rc4.cpython-310.pyc create mode 100644 appPublic/__pycache__/registerfunction.cpython-310.pyc create mode 100644 appPublic/__pycache__/streamhttpclient.cpython-310.pyc create mode 100644 appPublic/__pycache__/timeUtils.cpython-310.pyc create mode 100644 appPublic/__pycache__/unicoding.cpython-310.pyc create mode 100644 appPublic/__pycache__/uniqueID.cpython-310.pyc create mode 100644 appPublic/__pycache__/version.cpython-310.pyc create mode 100644 appPublic/__pycache__/worker.cpython-310.pyc create mode 100644 appPublic/k diff --git a/appPublic/README.md b/appPublic/README.md new file mode 100644 index 0000000..e4c8dfb --- /dev/null +++ b/appPublic/README.md @@ -0,0 +1,58 @@ +# EventDispatcher + +生产级异步事件调度器。 + +## 特性 + +- 支持普通函数 +- 支持 async 协程 +- 支持实例方法 +- 弱引用自动GC +- 异常隔离 +- 超时控制 +- 自定义错误处理 + +--- + +# 使用示例 + +```python +import asyncio + +from event_dispatcher import EventDispatcher + + +def on_login(data): + print(data) + + +async def main(): + + dispatcher = EventDispatcher() + + dispatcher.bind( + "login", + on_login + ) + + await dispatcher.dispatch( + "login", + { + "user": "张三" + } + ) + + +asyncio.run(main()) +``` + +--- + +# 项目结构 + +```text +event_dispatcher_project/ +├── event_dispatcher.py +└── README.md +``` + diff --git a/appPublic/__pycache__/Singleton.cpython-310.pyc b/appPublic/__pycache__/Singleton.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6d8d27d7e385affd465317dec12f76c840db3ba GIT binary patch literal 1908 zcmah~yKWmt6rGuUaJeEWn{ezT&cg`OY$H|f0z-x!SQQ}%lEo+)DC|zznolBOyt6#1YZGK;-6UnIz;bJq zztTRAteNg(`TOzVyeib;T}s0_fogJHF%@TZ*6f4>mE9O_?TF zkUdIp&F>Ol%<_b+5N~cJ&64k)hwLv&K!mPgpx$=G! zm(mA5J=sH4f$^Trvs~_mB)M#Ge^7Md26k(gYBX^xWz1f4Yiy3kqK7?G9J)fBA9Etvf6P zj~iZ1FOKU*$1z28Ne1C}*!i`RYlz-wv1>F5vAW z2(7o#R+g=368SeFU?KRB?0t6Ks5NhkM}?z?)RZG|C<137G;w!gK|7G*9rBNpQs!!R zqsc+{_H-#y0{TND*Hg6D#YRal;KhDx`~O?0KP6jq_jgv$CjW>uJ_p${-PO&zwQf60 zMy4pp?&=B@jCe*A%80o#{yZrPr3txNK8Z%=-sYJ+keh#iCeYYBZ!e*Z!T6Q^KiCGe zMtN$u)c48016UcZ41cv%yiF@j@KyT~Jt3^sk3a@|Bt(DA14rOpvpYZFV-fIx-{g`kf)l+TG8KXJV-N=!FabFZKwK;UBvKes7;_kM8KW2(8B&;n88n$+G6ID) z8E#mD<;GTmZ_@`^zES27f_04Xr>%S1mTKQ~oBBef_uwKy?TzbLgJ xzgR!9prD{MDJL@-#0r40;^Q;(GE3s)^$IF)aoFVMrd*(HR?^x4RVg15pwSh|VHf z6lFV?qKje)(K#DkzKE`f8;H)!lDK)~sGr2G`hr-km*t#XkmaFMUzGFk7U3<)WpP`U zUpV59T!g(VmtHu(21AZ~c+K9`$}8e#ugc9-FA^f|98_Hs?8d!AsZ2g7Y@^?JR2vmLj{dphxCy52iBE_Tmh<(UUF!%JM1 z;QVVMismZP*aW32z&ByPlc7{IG(Jn?6Le(?5Vp+B!!y2}PPo+qnMIgupCmxUUHS+{ zvjH1&VomTPrb+`yR^V-gmDxjfiqRUgW1d>Y7|Q#Lb7K;(x_hrG*yD_<^AU>Zwq>X4 z823mb|5is|gNO0W2ZS`GbV45TIqtdPUj^=QbqgVN1IFZf?I`YO`J--8!Okxq4&4^~ zH*hB4ndaKbimttpKV~`@0_b!1)EPLVDTu<=A>@z~&X^-vZ{Uvd0}m2$N7ECDxK^wa z@x9K+X?JaB=d;h(KCKoqV5B%j)EW1yCpASljQeEwYZZ`}lbx12?&+?wWi|ocq3lal z^KEKsm1YMmdlJ;U^fGM=EE=TuHwl}KWZIZ)-H@#&v6GTWLVgqESy|nqP4d}}|0iW2 z2c%h&azxUpr$O3~kEV&n8dJCN;cM)u3Zj-B^$vL%J3^kbb0K4^O%q@QJVEo6n)-mu z`(!?ZF@*^=Rt|6FX0kDHQ^AT$+?2qM`j~d{uCYR8q=WBtsa97G#+7`CxqtG3?6b@q4g8b^<%1mE zp@SN(VKN}vG>8a`JgbQ%?;QRnjd?)TRG+|ovlbS5wv3?Du9u+ax!R`nVWW}YTsIn~ zy!}w`Y(D7kH^1B3RB?Yt{-6#{7WHAAR`8!zv`lpcY2ugT#OXdhaql^_H*0H!$6?)Lc`N hSjY;z%nRJ%C9mX#-cqYD%n literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/argsConvert.cpython-310.pyc b/appPublic/__pycache__/argsConvert.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03a9cdc04cdb36e23fb70459f68cf4cd1acf0ee9 GIT binary patch literal 5915 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 literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/event_dispatcher.cpython-310.pyc b/appPublic/__pycache__/event_dispatcher.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..200803cc0ffe626e8160d140235867f6a9a30650 GIT binary patch literal 3931 zcmZ`+-ESLN6~Fh+oexiJCr!Gg?RG_W*@ZQ%96$nzRZ_OJ3%dd$q%N#5sz#HUN$k`f zJ9oxgVog?sL;@ao;gN!rJgxF~@XjA_UwJ~jfy6_lH2lsT+i{#Q)||QD=kxx~alcmc z8J?dvz1_c88T$uyW*-Zk5AbGfkeJ21%Ub1^x47wxmM~wdW#KEjvS+vKp3`zTt+Tpr z&ue+TN~_ZITYhh$wZPerSS(}vh{g7yXjRd3Vi!FZy;{s4vxfIiaATVdp}mJ;w;OJC z6Ky?6_Zw2%ak4es(RQL#U+GHn>nIuIoqnp_XQ4_v=}tsjXP>DG_c59<5*s4(#M&0I zh^-^pl8IdkbjVvyDNM_ay|{A3T3+nO3;0&zDg>+P>ZeKgl!V#}qo-PK57Q_TGwi5M z93SG%h-1!y>ZA^O?xdG{1wW+Km6$zdr+l;FYqyhTgCxrJ zN+*l@sz1y-X+o@x=Cz=c1=C^eb+TTPxBD?n0$EkEt$h;ur{$mwXv88S+hNw$c0eE4 zT4qUiTU8+QDO0!bdAYvU?)Q?lcA|Po7IxNDGU#V(;b1TrZgo2mwSHE%lFyPf58_TX z2=fT*n}dDr1wkk6^pYw6TS7!}Enq=e_M~v=V;ySzP3TN73oamuZuw!;I!}|ut)LkNU z`V41lC&_8tF!cCn=@LUs{{LX1lX6z@oF9t54_!sUcg0gN(b&>{Cqp3QVHzchq*6CQ z8p4=B+x;ANpO?o8f@CiU-k6AVi;q?=iB!&C(SBlgb%*$jEl%vN)f%3r7z%>b2_J`F z@o>3~C7+eq$R7*)GThM8q5b0f_jEH1HsRa84p) zH?g;+fd@%&F&!bGkN}QqTru_2P$gaUMP)2M9D!UI@aa!UDAl2`UM7N{8Fp4a~jH)K{@heT~SwL>eFsyS#eWOwBmO z_=DU?%M1oM6-PMS;XWVTo>P7b1KKa~gkr$}Qe6u?dV*tJLWmm@<6lG|_Ualg8i0Y({wG ziz>e@MmOixphZ_CCaLMoHbJHmyChK#HyrXmu-~z5PBC}nkv;{#!yYk81=POKCwr$H z*)ZDB{)V+V^*9bU-X;UB;LXVRZ5ZQ;cYr+fd-l{)0G2h}isAJLhF2M!b5}h67|51Ed?C4qtl{zMxo=mwJRjY{A?JK*OglR>8Ivrx_BS{?kerR`xr})sU$DQz zeYE12*mod5H+QIPJ>$=S(3_)oe>ErdlhsQ%c6B@Kbd&h~Ra`5&U5aw1LPf@O<-=)> zV-Hj(%_lc+8l~Do8Kik~;m*>S%Yhn>0c3&WD5Y@D3Aq$_ePyTNVH}8a;6P`;fCEvVjvBce z%R;{t;~2P_YwGNH_Z0asMFWpvk=wQHkHA7 zKgioE31dazr06ObxW>#hXZTpz3-bW6qTZ(k6b22qM7(d&00oqmafs_r=~GK8D%JOB zY6=u(WG&&8BpT+)B(B<6l>GukJoj9WVoEr|!%NX6dG(dE;{V&JJO7o!FZ-VN%0VG$ zB2LIx!jfn5+;Qt%T9YVr5RY|%IQ-XW^-3Jh37{T;`6bXLgr?VEz@O2eP=wPcQFw#{ zJM6#$^p2tSkUwHi?oyZ@3xum(*d|=xEG*RQl9I>X4TJ&a2`w(d0HYRm`q()>iNevW zZ;tsf_3>mb`*GR20B@3{%(qUNl4Q4&<;LmSL4lp5v3dyUwTtRH3RT>2W|9<9NF`+v`H09xe3_Oh8{Wah+jz585RVDF zjEm~a<)vlUTlDUUAILKy1Y)Otrf7AeuGaA>!SnmnS_DBp+aKVcVJQdk)V1k9mnI6U t^1e{cP!uqVK&(trbm(=mX>Yx(Tklh$oGpQP%tJo(_!7U(>(=t?{{uJWR!IN= literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/folderUtils.cpython-310.pyc b/appPublic/__pycache__/folderUtils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26411745493ab879942d2bd09740947d8ea444fb GIT binary patch literal 4510 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 literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/jsonConfig.cpython-310.pyc b/appPublic/__pycache__/jsonConfig.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0763beffdaf8208c07c8286123cac68b29bada3e GIT binary patch literal 2060 zcmY*aUvJz*5Z_&||D5k~x#k~jkx-B-z%5EB2!v3Jidux!hodM$m5h+(c=r-teD<++ z8glZXitB6n1U%#^vBu3&*+R%0@4OZ8;vCB9^7Y-1Y0lQZloVj z%^$_pA*}v`G^xJaAIhWxX>Bjf4>DO5`2(30Dy|9zyX{A+I8gEE{FU}+>Y%(|mcGj?9xn$bf4uz^@IRDQ_yNAU{ z?jA}tl4YFkDmgC7-FQ46AMa;rg50Bq8o$;ymj^ye4abBh^G|hl;rdDA| zV7@XeknX`OuLF?;GYeUzp(Px_g$)ts!UC^d?LPz)O=Kp!erqXhCs|yU+gTBdZFFOM zpo-CUe9ott^jn&vGyMdEa52y|M4*YzpTJb4rZYO_HLoB$GkV0z-jY{a6|JdYGd8tz zR@13HxixVsc4pP~oKBs`B;Vwu;-?={GIc4Lv?^OzH5od!JF_UM-5=p@Q}+k=gr1Pc z=hiMPsr$8k=FTBqdAIRnq50}Ub3#r?Z3%Kr0SF#O2Ym5r@2pijwKZo`r>3#OD8d*X7MYML ziZtu*1s%<+)3MaN7|UF9)N796)~(MkzM$=~O7lu>Kp?f9WJM_zR5j6V(jZe|rnMJE zX`WV56hKZ&nGLkRG^bsF4O&v0c-9#n8nbkuFi)CF&EmuWvmssBRc`>f2D5w*h)1u| z4&{u~u6a21p0fYg%bx8~_O$oXr|hL?`EbUAXNykOA1*+(vv7^6EAXv;V57TvJdzLx zKZ-_$IL?soMA3K0adxh8qev7<6d6x0d4~n0jEgMH2Zz`-GSn4e}q25OF4iaN*NsQT>pxA|JN*~NJg*ypW7bq z(m7zR@&S)r@aIrDwGEfC`jdo88btF=y@COi3gN2}NB+Uxw zSqHL8PK4%T=$P7#_e;a@VUgzADl4V%hU#4)+BqJJxRU1Lfuj&24Yt^Ltes?lDby@4 z4Zto15#y&@V5kZB2OySLfj9;?SE+9?%Bb_NXCsz4RUhLEfR<65=27$l6KOyM{=W(Q z#KxQ6ojADMz8kQ9KX^^;;7e9{S}OducJUrrx^Mi~8;jn$gRQw~d`%IpFI9{GgTmIP zH_ofin6nKJl5;5>uV4|uh*q(R+p_&{`ddO;psL2 literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/log.cpython-310.pyc b/appPublic/__pycache__/log.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..926c485a2e8deb0c4e08abcdb668bc33ca1b08b9 GIT binary patch literal 2947 zcma)8OK;p%6!!IdJkGl<3knoUAO!vj8dO=1uV?DiGajxzlti8l z>6Q)K7HP7~KjAmrEvxL1x}qz-bDi-_f?CCv&pqcpj?d#e$IcfPJPp@hzyFgC!Tn9b z{AEJ8g{Sxfgln8-TBjaahe6gey>E03Msr4H_N|Vkcr&y6PRCI^%iNC3Ep9*5I<3U{ zO5+Z9A8On^)DKz5<1OxCrOn&i$LR9~zKC&wFY#rJi+qKzVqD^D{1V1xewkmvxWd_v z7QAo*yR_|qNw1rWepH6ZuQ4RQO#4YuM*U$?3dpNF>7bV-Wj?r_#JPydT*P#8dXb+7 zo-gneZ-JEBgdJ&PtQF!brx*1f!+Y~4!)JdV;Wkqq-FY+a%%I3>_1*5}P`5H!-w~@Nb(*1V-o4nUc#EAp7CpHm_2xa4h(s7~_VIYAc zy*Nt|SQQ~tQHv+Lqn>mgL}GyaN-Gf}7qSHmBtvpfy0J*h6yZF$v%b+_A}D@Z-=Kg7 z#a(b&@=KD<#A$MZ;zO*}`6=$MZy>xy)WaE1yabE3V={AkodMA6n5|f)g<7S9g4@#p zApMBu%*p_@2s(ni1$a!A+*V_Uv=v)O1F(^n5~PFlk!iq+StMCkyoST#I*~Vt5EyE* z0#3Riu#}czcomXLv5gcjGLIdsOyj;e-4j!Yrx)>Ln5u;hFfd;eizS=DnLYFXt{;&L z3jL+IXHEIQ*p@6hutsI~#s`6|%#wDT^CT{$nGcfz98(FGMzLQ=yC``+Dvz0dGq_u;Dy>QpvWZ4xjID+@ z$2RP?CN{O8u~RvaocpG@N*F5LL-MT!yy=xy*_=JL$8M!fJn|AN?aIBPja%US$wJjS zVrtf(EY|Cjr8*j@NSzv4tErM1z@&4EeL-f6Hb}56s3{0aif9pOmIT3HtP^>Ih(Sbw z^<8jieyUNURO=`|K!qmK>Sm+jp16q}fmh?S zO>8L06l!dAd(6~vGyU|opSrH6=6!bHHz~u>K(8x2Xi*taafYGv!myw75n6F5{V@D_ z6sevOhPA)%lX(FV@=`e>J|b>bmx`m}6l)+P6;zzArW;e6Xte(|TOM<5*Y<6-^9-;l zn$zlhLQy^aQn3;Z`H+qE3ay5tQUMnAT}EP2m*)5Q9EumQ|JbaPM(9)Om6^xJT&O8A zb9O6}>F8}dPblLqbJ;3W>Yizw_!JxQYHf!s9ta$6{KtzPeD~rKPZbe>}Wn%6;$BjZ4mS<5yc7pXbF0sTx3mX+h)hMakqOiVrDQoLL$!d{$HfkhaQcKwgI~usL zSbl7&-72cU0E|))|XiC;k?AWeRG-cXaaay!RW4KNn+ijXCX=K1KdmvVvp|mo& zWM@~lB~U;C8E7tU4?PA!Ngx;Bdh4y{qL<$1+LLc--JjHM<$iCLB1O}7SDLqPX5Q?) z`QFbwc4lVs4xT^W|04V|xW7>6=#xX|5?cHV<~Y)ktmV|wH>@`Q`Wd5Eb^ZUG3mIYbF=rL81GqtSC+^2S#43}`b$=>yzIz|oEx~mzF1pU%l%gdPVK~Kc78OwSUaiQ z{;TRFNeo!+6!ux{pH?T-se#?&29OetaQ0p1MCJ2N{M$R&kN$3=9i5eIZK@CX-yfAH z8EVzz56L#GRbdKOqT8YFL~Ru%rhGMQskNOrQSJ9TfmGV$-w9$hcwER$h}1W&yKdv{46q_8awd@hs+I(!pm%rYm3?XcG_3UP6mkL6k#Y zSmTmO7Q*+NLb_7iV>Nf^(PHS)nbeWm)4rUQWxR9p7;Ih9Gx+G^%y!cJ z*7vVAJai5pI`#;hKcUm(J*V#UTu_$q9st^c!`$b4UgGvV$)$UrBm~qFN#-|9W)ct7 zOR}KZ#0T}09B3}dgXWV0Xdx+r7V)hayl3z(;ay5*L1)n`18SKdO|lwBZ5XG9E@6Zc@-|^tEkbDu*p?e*K4IdT~tx9-ct1- z-iaDUY{i|(WH*C2NMKwyL>y$A5KWA0t)1+2mGvv*wp3)i)Tp`yxHN%jO6kaZ_zuO7 z@j7ugNH(W}Ap_wxw0Hp|akkhN?*r++0G}DK0Rl61M9=U}Yy^D-I;bvm?1YiY#NAey z7%ylg7<|ACyZfvM`WIS3dtC+>zef8|94t7y-+0!m&(-T;6ejihxeKjMBWT4J!KCYq zzm9;9g0`AcpCZYsPccU7_u&d-rCt3MjO(*RUMKPzkx_Wt2+>uH(YRHu=$OjkZa2bY zv$LICxjUUhMzAemVY;uSfQ~?uY?;i>S2ZP^su-(bd<&Smo4j11uOBM3D9OXDAU5oOi*V-Sydtb{+#1mjNy=Lf>&{}qD&M`ZXD;qk{J%l|EW z{-u}W|MK$upQ6D3;T8Gc{TcqqFY&+mv;41qS$t8d2v%X@>F)9ieRsk?2_nMkGO2PH zUa5cXvBd2Qivi4t6x&qA`Wp^|a-A1xo1CLy6TTd>{vDfJ*Qp$q9T(uIuQV{}V|xII2+ zzhZlC&rJi89Hz>wHzF>r3jX2Us40$&*#1~ep_m=so8N_mg{{m5+g+N{YbZ9M8yS*x zBfK7wEC14IB1k2_=R+^2k5aMc4mfU(A$kM0Cot~z#3v4w0#&ivz_N*l63ZOgBl_|u z$Tk+{vGE@;dzy5>RsuPg^qP&g3$%{h6Gxa%#KY=hoQFs2jF-kMfcqgQ1|! zRvG#o3|CWMHu+&~f}1W?&!-Vz$4f|Bi&}j{89`VXC=5!hS z7|oXC6(poQ`|82&=@%ULu&7zB<|*OR)mX2ae7)Z8$ZgzNbyKX@f4&{G(i#0dd|8vv zr(SFEv=@=Rl4$QE-Y`~*DpZQFn6iTJRG5Fl7ryIf{A@96>(_~*o)%KGxc?4Jg8V~8 zePW9es#AgfWy(Z-ciCq>Wu)cK6>W$nr=3T#@ru;=&u zzTZPthD?#2wAW`>=blz5{-l}2eG*$bW&b^yiftRircBh)N z$JHOw)JGsjXaz%C5GN}vlewcqT;w^uMshrg^)bsdrD6DAH$FK6S;nxg;dh!xu(xT- z!=~5UEm9+ZOBBR4S`rVl+azzx8RKn*(N^%Lt#Z@TuFl{qcJ(F+$x96N{Zi+`_4ElI#yi zmN(Cv3`JY4e@27W6xMgg#KP%cNTcE+fe>E=@c}6ZoF2ej8ba$cUzCLZmR|seYH1#G VK3@R8fL?{2Iw&1*e)d3o`9BoP#3cX# literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/myjson.cpython-310.pyc b/appPublic/__pycache__/myjson.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..086026bf68f0b5231651a677c7ebc41f351457d3 GIT binary patch literal 648 zcmY+CL5tKd6vy+@B-0&tMnv!vh|r4zo;-*M-WOp(vA5YKb!TWNC7B{Cvp27Phnb__ z#LtkcCvToT`G4sOYfAq8zchI-zodS#mkJ&AHo>_sX)QIhCX+JVekGkbmtztY;X_SOhEytRiCp~p09uMd1Kfv+biJN851k{~Ml)i#{*H@?{LfQ5-BS;8gF^INu&*DvWDPk0PlQQ+gR z&XOLPD(9cdF+`pdX6zn8Cg3>bi}$MJdbw2js`qy6+-v+>B0hmgaZZL$M$YBj7;SR& E7Y9;;egFUf literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/objectAction.cpython-310.pyc b/appPublic/__pycache__/objectAction.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4620aeb34f2610491729ce948c5e5c3223a64fc7 GIT binary patch literal 2014 zcmbtV&u<$=6rNvRuN^0(PJxC42vU%?LNVADr3aB|?(N@*@cKFn!neAqzL>$Q+KV~DZ<@i2x;@Bgzun`Fh@0A>xGEz3cUSzroYQUAu z^ohq=lMr%+sIedqU8Wy#y5lWBHqO1gKHZxNl1s~!HUx+Nz--{;U^4|vfO}rj0PqnC z8o0m_r#<%t1OJG9A6_(F(~*vo3wa@*AC$rc3$7*I$P=%x@b!Oa9{E&r`;AldEu{+n zqDDUwFZn^m@7dcFrNx!7dqkr3{K>JIM&ZAbr;{?N!ZaC=he`U(r_tV`Z!3OwGnGyA zqeRwY)XjE5_CauQ*9dB4al^~M)8!pHi|{S(zTy`A8y#3A%LA{?d;s<}5MZFzz5gkWKLq)R z$p5tVptrJi0BbZ?1He~}{RuH8Td)giX=+t!)>2$aYOR`+r38mN8L57yN>h{-AJ+Y) ze2VMpAOjYzu6ZT$W_LoR_0X!WhM3;wm>4r%E3j)>V>W_Z_&dzR% literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/rc4.cpython-310.pyc b/appPublic/__pycache__/rc4.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9480b88669b6d775d96fda48b784bbccc3d1d6c9 GIT binary patch literal 6030 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%0AhJ?Y$lIsE#ycGcjrs0X~anUS!{lQ1rdsV zz>2-r8>Z4tjt0FjHkELY4Dp9a7F*Uu{O$bVa-Zf)-a+Lfo8`b_K9dsV+fCuG R;|Y@gstD_#mOSsPe*>&ZGNAwf literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/streamhttpclient.cpython-310.pyc b/appPublic/__pycache__/streamhttpclient.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..888e7ad7a513af88cf0d9163e160fe0d0a21eb1c GIT binary patch literal 5919 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 literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/uniqueID.cpython-310.pyc b/appPublic/__pycache__/uniqueID.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a1d8d73f7812065e05da1a743849d4780b9b0cf GIT binary patch literal 1067 zcmZWn&2AGh5cb&K&32oF78L|kh;rZ%2}plZaiM@jFTF%ay+uM%x^~lTlik$2sYJCo zZBIyjf(ofU_Dy&OUpeK*86m-pfl`WBp83X}o%uX7X{{DAT%S+B#x2g+7c#CdiN+h; zS%N|_1q0S0%?B{#9S%(0Qc`&*&=G1*RaAgTs(BTvSwxG*mk>ddx|+(`x0!>*NHa0T-*BY?(*`=%IfOcTC26b z9s#-hUW94C#hnpx#kSccv@cl$EF{LqBPYJKntSO`H}|v|>Z}(xjUJ_0vo{)z#yf*J zBJ}PT8Yl7LSZ{4UAAPWuOy})XX$qZTv6uuigKByQ#eYl$9y%se;G7lsrc-=bgVTd# z79VRvG0ZH9D{3Y{(|UcKZ*5i(x;!D68saH=MfB63MIIh*m**pboaIok5(-#EIpGQ> zqR%E0wU=|n3x39xDBz5Lk|hAL+GOvaO#DI={J=BM3Qx(qY~mI2T;#IwO1MBTic)yF zSNJ8opj)9l)BJ4Ir zqtYcGN|-I7m;>p)1qj?%N2`jcikkljxgn>2YD@j2TD#iLA)p>oO$&}M=G)9rg`kf)l+TGR1)OV-N=!FakLaKwQiLBvKfn7*ZI688n%ySWWdz^$h$p8E#mBE?C}IMt0~5cD^)vEwQ}r`ai*i$o6EpRTQVa5n^%DyU3QCi5GLu29 d00;}JU$3C@7Kcr4eoARhsvXGUVvu1R3;-e}D8T># literal 0 HcmV?d00001 diff --git a/appPublic/__pycache__/worker.cpython-310.pyc b/appPublic/__pycache__/worker.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f05fa9ef51a894b173dd83b13e4364d3d997fe47 GIT binary patch literal 4390 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 "${PROJECT_DIR}/event_dispatcher.py" <<'PYEOF' +import asyncio +import inspect +import traceback +import weakref +from typing import Callable, Any + + +class WeakCallback: + + def __init__(self, func: Callable): + + self._is_coroutine = inspect.iscoroutinefunction(func) + + if inspect.ismethod(func): + self._ref = weakref.WeakMethod(func) + else: + self._ref = weakref.ref(func) + + self._hash = hash(func) + + @property + def is_coroutine(self): + return self._is_coroutine + + def get(self): + return self._ref() + + def __eq__(self, other): + return isinstance(other, WeakCallback) and self._hash == other._hash + + def __hash__(self): + return self._hash + + +class EventDispatcher: + + def __init__( + self, + *, + continue_on_error=True, + log_traceback=True, + handler_timeout=None, + error_handler=None, + ): + + self._events = {} + + self.continue_on_error = continue_on_error + self.log_traceback = log_traceback + self.handler_timeout = handler_timeout + self.error_handler = error_handler + + def bind(self, event_name: str, func: Callable): + + if event_name not in self._events: + self._events[event_name] = set() + + self._events[event_name].add(WeakCallback(func)) + + def unbind(self, event_name: str, func: Callable): + + if event_name not in self._events: + return + + target = WeakCallback(func) + + self._events[event_name] = { + cb for cb in self._events[event_name] + if cb != target + } + + if not self._events[event_name]: + del self._events[event_name] + + async def _run_error_handler( + self, + event_name, + func, + exc, + ): + + if not self.error_handler: + return + + try: + + if inspect.iscoroutinefunction(self.error_handler): + await self.error_handler( + event_name, + func, + exc, + ) + else: + self.error_handler( + event_name, + func, + exc, + ) + + except Exception as e: + print(f"[EventDispatcher] error_handler failed: {e}") + + async def _execute_handler( + self, + cb, + event_name, + data, + ): + + func = cb.get() + + if func is None: + return False + + try: + + if cb.is_coroutine: + + coro = func(data) + + if self.handler_timeout: + await asyncio.wait_for( + coro, + timeout=self.handler_timeout, + ) + else: + await coro + + else: + + if self.handler_timeout: + + await asyncio.wait_for( + asyncio.to_thread(func, data), + timeout=self.handler_timeout, + ) + + else: + func(data) + + return True + + except Exception as e: + + print( + f"[EventDispatcher] " + f"handler failed: " + f"event={event_name}, " + f"handler={func}" + ) + + if self.log_traceback: + traceback.print_exc() + + await self._run_error_handler( + event_name, + func, + e, + ) + + if not self.continue_on_error: + raise + + return True + + async def dispatch( + self, + event_name: str, + data: Any = None, + ): + + if event_name not in self._events: + return + + dead_callbacks = [] + + for cb in list(self._events[event_name]): + + func = cb.get() + + if func is None: + dead_callbacks.append(cb) + continue + + await self._execute_handler( + cb, + event_name, + data, + ) + + for cb in dead_callbacks: + self._events[event_name].discard(cb) + + if ( + event_name in self._events + and not self._events[event_name] + ): + del self._events[event_name] +PYEOF + +# ========================================================= +# README.md +# ========================================================= + +cat > "${PROJECT_DIR}/README.md" <= 0 or item.find('[critical]') >= 0: + fh.flush() + except queue.Empty: + # Periodic flush to prevent data loss on crash + if fh is not None: + try: + fh.flush() + except Exception: + pass + except Exception: + pass + def log(self, levelname, message, frame_info): caller_frame = frame_info.f_back filename = inspect.getframeinfo(caller_frame).filename lineno = inspect.getframeinfo(caller_frame).lineno level = self.levels.get(levelname) if level > self.level: - # print(f'{level=},{self.level=}') return data = { - 'timestamp':timestampstr(), - 'name':self.name, - 'levelname':levelname, - 'message':message, - 'filename':filename, - 'lineno':lineno + 'timestamp': timestampstr(), + 'name': self.name, + 'levelname': levelname, + 'message': message, + 'filename': filename, + 'lineno': lineno } - self.open_logger() s = self.formater % data - self.logger.write(s) - self.logger.flush() - self.close_logger() - + try: + self._q.put_nowait(s) + except queue.Full: + # Queue full: drop oldest (non-blocking, never stall the event loop) + try: + self._q.get_nowait() + self._q.put_nowait(s) + except Exception: + pass + def clientinfo(message): frame_info = inspect.currentframe() logger = MyLogger('Test') @@ -97,8 +137,7 @@ def critical(message): def exception(message): frame_info = inspect.currentframe() - tb_msg = format_exc() + tb_msg = format_exc() msg = f'{message}\n{tb_msg}' logger = MyLogger('exception') logger.log('exception', msg, frame_info) -