}s.ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z ddlmZddlmZddlmZmZmZddlmZddlmZmZmZmZmZmZddl m!Z!m"Z"m#Z#m$Z$m%Z%dd l&m'Z'm(Z(m)Z)m*Z*ddl+m,Z,dd l-m.Z.dd l/m0Z0dd l1m2Z2dd l3m4Z4edgdZ5ej6e7Z8edZ9dejfdZ:edefdZ;ddedS)N)OptionalDictTuple)contextmanager) namedtuple)BoundedSemaphoreLockThread)gettext)cpusersget_domains_php_infodocrootget_installed_php_versionsget_main_username_by_uidcpinfo)get_process_pidremove_pid_filewrite_pid_fileis_litespeed_runningis_nginx_running)is_user_redis_alivekill_all_users_redisesreload_redis_for_user_thread parse_redises)WposDaemonBase)WPOS_DAEMON_SOCKET_FILE)WposDaemonLockError)PendingSubscriptionWatcher User_data redis_pidlocklast_reload_timec#bKtjd}dVtj|dS)z, Context manager for dropping umask rN)osumask)prevs py/clwpos/daemon.py_umask_0r)4s/ 8A;;D EEEHTNNNNNreturnct5tjtj}|t||cdddS#1swxYwYdS)zr Create world-writable socket in given sock_location or reuse existing one :return: socket object N)r)socketAF_UNIXbindrlisten)sockobjs r(_create_socketr2>s -// ,--- sAA**A.1A.r"c#K|dsttd |V|dS#|wxYw)z= Non-blocking lock implementation for with statement Fblockingz/Can't acquire lock. May be it already acquired.)messageN)acquirer_release)r"s r(non_blocking_lockr:Ksj <<< ' '`!!,]*^*^____   s AA'functioninput_parametersc|rd|Dng}tjdd|g|d}tj|jdS)Nc"g|] \}}|d| S)=).0keyvalues r( zwhmapi1..Ys*\\\ZS%3 0 0 0 0\\\r*z/usr/sbin/whmapi1z --output=jsonT)capture_outputdata)items subprocessrunjsonloadsstdoutdecode)r;r<input_parameters_as_listresults r(whmapi1rPXs}`px\\CSCYCYC[C[\\\\vx ^0/8gNfg+/111F :fm**,, - -f 55r*cReZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZeeeee e e e e eeeeegZee e eeeeegZdZdZdZdZfdZdGdedededefdZdedefdZ dZ!dZ"d Z#d!Z$d"Z%d#Z&d$Z'dHd'efd(Z(e)de*fd)Z+e)de*fd*Z,e)de*fd+Z-d,e.j.de/eee0ee0e*effd-Z1d,e.j.d.ed/efd0Z2d1edefd2Z3 dId,e.j.d.ed/ed3eded4ef d5Z4e)dJd7ede5fd8Z6d,e.j.fd9Z7d,e.j.fd:Z8d,e.j.fd;Z9d,e.j.d7efd<Z:d,e.j.fd=Z;d,e.j.fd>Zd,e.j.fdAZ?d,e.j.fdBZ@d,e.j.dd6fdCZAdDZBd/edd6fdEZCd,e.j.d/edd6fdFZDxZES)K WposDaemonzW AccelerateWP daemon main class. Socket operations, redis process control, etc z/var/lve/wpos_reloadreloadzget-redis-statuszget-litespeed-statuszget-nginx-statuszget-apache2nginx-statusphp_get_vhost_versionsphp_get_installed_versionsget_upgrade_link get_unique_idsuite_allowed_callbackdaemon_register_upgradedaemon_get_upgrade_status&daemon_get_supported_suites_by_licensedaemon_is_owned_by_resellerdaemon_is_wp2_environment2c(ti|_g|_d|_d|_d|_d|_t|j |_ i|_ t|_ t|_dS)NrT)super__init___monitoring_users_dict_username_list_to_process_socket _reload_uid_socket_thread_socket_thread_workr_MAX_CONCURRENT_CONNECTIONS_connection_semaphore_uid_connection_countsr _uid_connection_lockr_suite_watcher)self __class__s r(rdzWposDaemon.__init__s  =?#)+&04 04#' %5d6V%W%W"68#$(FF!8::r*nouser_uidis_store_last_reload_time force_reloadr+cB |j|}|d}n|j}t|}td||t |||\}}|ddkrCtd|t|td|j|<|S|rv|j j r|sd} ntj } t|t| } | |j|<td|t| n,||jvr#td ||j|=nB#t$r5} t| dt| icYd} ~ Sd} ~ wwxYwddiS) aP Starts/stops redis for user and updates dict for monitoring (self._monitoring_users_dict) :param user_uid: uid to reload redis :param is_store_last_reload_time: True - write last reload time to user data, False - write 0 :return: dict {"result": "success"} / {"result": "error", "context": {}} Nz.Reloading redis for user: %s, force reload: %srOsuccessz^Redis reloading failed for user: %s, adding to monitoring list to try again in several minutesrr z)Saving user=%s to monitoring with data=%sz Removing user=%s from monitoring)regetr!rloggerinforrr _configenable_reload_rate_limittimestr Exception exception) rprsrtruuserdata old_redis_pidusername new_redis_pid result_dictr#user_redis_dataes r(_reload_redis_for_userz!WposDaemon._reload_redis_for_users' &266x@@H $ ( 2 /99H KKH , 0 0 0)E-*7*7 &M;8$ 11 CDLNNN9B+$&&19N9N9N+H5"" >|<3D]3'($$'+y{{$"+m$&&Sc#e#e#e8G+H5 GSVWfSgSghhhht:::KK BHMMM3H= & & &   Q   c!ff% % % % % % % &)$$s%B3E6B$E F%*FFFc|j|}d} t|j5t|\}}}|s ddddS|r ddddSt |}t d|t||j|j\}}||ddkr ddddSt||jd |j|<dddn #1swxYwYne#t$r,} t d | j ||Yd} ~ n4d} ~ wt$r$} t | Yd} ~ nd} ~ wwxYwdS) a" One user monitoring actions :param user_uid: uid to reload redis :return: User remove flag: True - user has stopped his redis (or user absent in system), remove it from monitoring list False - redis still active, should be monitored again NTFz/Redis instance died for username=%s, restartingrOrwrr zSLock error: %s. User %s (uid=%d) is working with his redis, skip monitoring actions)rer:r"rrryrzrr!rrdebugr6rr) rprs user_dataris_redis_aliveis_user_presentr8r!rrs r(_user_monitoringzWposDaemon._user_monitoringsz $:8D  "9>22 V V5H5R5R2&  V V V V V V V V"!  V V V V V V V V4H== MxXXX)E/9C*E*E& ;$X)>))K)K V V V V V V V V 9BI\e\jST9V9V9V+H5! V V V V V V V V V V V V V V V$# > > > LLn y(H > > > > > > > >     Q         usjC9C- C9 C- C9AC-5 C9C-! C9-C11C94C15C99 E"D** E7EEcg}tdt|jt |jD].}||}|r||/|D];}||jvr0tdt||j|= > >D7<<>>?? 8 8G--g66I 8'..w777. 9 9G$555 CS\\RRR/8 9 9r*c|jrd|_t}tdt ||D]} t j|j}n#t$rY)wxYw|j |}tdt ||r|j s| |ddSdS)zC Process all requests - start/stop redis for users Fz*Checking redis instance for those users=%sz2Current user data for redis instance monitoring=%sN) _reload_config_needr ryrzr~pwdgetpwnampw_uidKeyErrorrerxr!r)rp all_usersrrmonitored_user_datas r(_reload_all_userszWposDaemon._reload_all_userss  # @',D $ I KKDc)nn U U U% @ @!l844;GGH'+&A&E&Eg&N&N# PRUViRjRjkkk*@2E2O@//??? @ @ @ @s A$$ A10A1c Jd}t}td||D]F}|j|dt |dt diG|js || |jrdStj d|dz }||j j kr|d}n,#t$rtddYnwxYw|jdSdS)NrzFound existing redises: %sr z,Cloudlinux AccelerateWP daemon general errorTexc_info)rryrzreupdaterr _is_terminate _force_reloadrr}sleepr{monitoring_intervalrrr)rpiexisting_redisesitems r( _main_cyclezWposDaemon._main_cycle+sa (?? 02BCCC$ y yD  ' . .QTRSW[_[a[atu9v9v9v/w x x x x$ ` `""$$$&&(((%E 1 Qt|777,,...A ` ` `  !OZ^ _____ `$ ` ` ` ` `s=/C..?C..&DDclt|j|_|jdS)z; Create and start socket processing thread )targetN)r _process_socket_connectionsristartrps r(_create_and_start_socket_threadz*WposDaemon._create_and_start_socket_threadBs5%D,LMMM !!#####r*c^t|j"td|jdStjtr| t|_ nI#ttf$r5}d}t|t|Yd}~dSd}~wwxYwtd|t!|j|||d|_|j|t/|jtddS)z+ Main work daemon function NzCPID file %s existing. Cloudlinux AccelerateWP daemon already works?z5Can't create AccelerateWP daemon socket. Error is: %sz&Cloudlinux AccelerateWP daemon startedFz)Cloudlinux AccelerateWP daemon terminated)r _PID_FILENAMErywarningr%pathexistsr_remove_socketr2rgOSErrorIOErrorr~rz_setup_signalsrrSrrrjrijoinr)rprr6s r(rIzWposDaemon.runIs 4- . . : NN`bfbt u u u F 7>>1 2 2 "    ! ! ! )++DLL!   MG NN7CFF + + + FFFFF    <=== t)***  ,,... #(    """ *+++ ?@@@@@s0BC *CC ctj|jrH| tj|jdS#t tf$rYdSwxYwdS)z% Force reload daemon N)r%risfile_WPOS_DAEMON_RELOAD_FILErSremoverrrs r(rzWposDaemon._force_reloadksy 7>>$7 8 8  KKMMM  $788888W%       sAA*)A*c tdt|j|jt jttdtdS#ttf$r9}t dtt|Yd}~dSd}~wwxYw)z- Remove daemon's socket file zRemoving socket %sNzSocket %s removedz!Can't remove socket %s. Error: %s) ryrzrrgcloser%rrrrr~)rprs r(rzWposDaemon._remove_socketxs a KK,.E F F F|' ""$$$ I- . . . KK+-D E E E E E! a a a NN>@WY\]^Y_Y_ ` ` ` ` ` ` ` ` ` asA9A==C.CCFrgracefulc~t|j}|rG td|t j|t jn3#t$r&}td||Yd}~nd}~wwxYwd}||kra t j|dn+#t$rtd|YnwxYw||z }tj |||katd| t j|t j n3#t$r&}td||Yd}~nd}~wwxYw|r.tdttt|jtddS) z0 Stops a working daemon process zKilling process with PID %sz4Process with pid %s is not possible to be killed: %sNrz#Process with pid %s is finally deadz:Process with pid %s did not exit in timeout, sigkilling itz7Graceful shutdown, killing all existing redis processesz&Cloudlinux AccelerateWP daemon stopped)rrryrzr%killsignalSIGTERMrr}rSIGKILLrr)rprtimeoutintervalpidrrs r(stopzWposDaemon.stopsd011  ` \ 93???V^,,,, \ \ \ RTWYZ[[[[[[[[ \Ag++GCOOOOKK EsKKKEX  8$$$g++ XZ]^^^`GC0000```KK VX[]^________`  + KKQ R R R "6 * * **+++ <=====sA:A BA??BB&&%C C D,, E6EEcHdtjtdS)zy Get litespeed webserver status: running or not. :return: Dict to send to clwpos-user via socket rwrO timestampstatus)r}rr@r*r(_get_litespeed_statusz WposDaemon._get_litespeed_statuss! $$)++I]I_I_```r*cHdtjtdS)zu Get nginx webserver status: running or not. :return: Dict to send to clwpos-user via socket rwr)r}rr@r*r(_get_nginx_statuszWposDaemon._get_nginx_statuss! $$)++IYI[I[\\\r*cLddlm}dtj|dS)z| Get apache2nginx webserver status: running or not. :return: Dict to send to clwpos-user via socket ris_apache2nginx_runningrwr)clcommon.utilsrr}rs r(_get_apache2nginx_statusz#WposDaemon._get_apache2nginx_statuss6 ;:::::#$)++I`I`IbIbcccr*client_socket_objc0tj|} t|}n=#t$r0tj|dd|it jdYdSwxYw tj|}nE#tjtj tj tjttf$rd}YnwxYw|tj|dd|iddSd |vr+tj|d t jd dS|d krd|vr+tj|d t jd dS|d} t|}n=#t$r0tj|dd|it jdYdSwxYw|d |jvr+tj|dt jd dSd|||dfS|d |jvr+tj|dt jd dSd|||dfS)a, Validate socket connection. Check: - root connections - connection user presense - command validity :return: tuple(is_connection_valid, uid, username, user_request_dict, is_root_query) is_connection_valid: True - Socket connection valid, should be processed. uid, username and user_request_dict filled False - invalid connection, should be skipped. uid == -1, username and user_request_dict = None is_root_query - True - root query, do not check reload interval zNo user uid=%(uid)duid)rOcontextr)FNNFNz>User %(username)s sent invalid query to CL AccelerateWP daemonrrOrcommandz0Daemon received malformed query (command absent)rOrrz)Root request to daemon should contain uidzDaemon received invalid commandTF) socket_utilsget_uid_from_socketrr(send_dict_to_socket_connection_and_closer}'read_unpack_response_from_socket_daemonr-errorrrJJSONDecodeErrorstructAttributeErrorUnicodeDecodeError_DAEMON_VALID_COMMANDS_FOR_ROOT_DAEMON_VALID_COMMANDS)rpr_uidr user_requests r(_validate_socket_connectionz&WposDaemon._validate_socket_connections /0ABB 0/55HH 0 0 0  ABSMbOTVZmPTPYP[P[C]C] ^ ^ ^0//  0  +7+_`q+r+rLL fnd.BFLR`btu   LLL    ABSNfOY[cNdCfCf g g g0/ L ( (  ABSN_PTPYP[P[C]C] ^ ^ ^0/ 199L((EFWR_TXT]T_T_GaGabbb43&D 43D99 4 4 4EFWQfSXZ^R_TXT]T_T_GaGabbb433  4 I&d.RRREFWQrTXT]T_T_GaGabbb43xt; ;  "$*E E E  ABSMnPTPYP[P[C]C] ^ ^ ^0/T8\588s3&6A A $A99?B;:B; E6FFrrc*|j|d}|tj|dd|iddS|j5t |\}}}|ddkr||d<tj||ddddS#1swxYwYdS)z Get redis status for user (socket query) :param client_socket_obj: Client socket connection :param username: User name :param uid: User uid Nz"User %(username)s has no redis yetrrrOrwr)rerxrrr"r)rprrrrrr8rs r(_socket_user_get_redis_statusz(WposDaemon._socket_user_get_redis_statuss( $:>>sDII    ABSMqOY[cNdCfCf g g g g g f f1DS1I1I.;x(I55,:K)EFWYdeee  f f f f f f f f f f f f f f f f f fs:BB B r#cL|dkptj|z |jkS)zv Checks is reload available by checking time :return: True - available, False - not available r)r}_MIN_ALLOWED_RELOAD_PERIOD)rpr#s r(_is_reload_availablezWposDaemon._is_reload_available*s(  1$h 6F(FIh(hhr* is_root_queryskip_last_time_checkc |j|}tdt |t |||ja||d|}tj|d<tj ||t d||dS|j } |sM|sK| | s6tjd||j dd }tj ||dS|j5||d}tj|d<tj ||td ||ddddS#1swxYwYdS) a> Reload redis for user (socket query) :param client_socket_obj: Client socket connection :param username: User name :param uid: User uid :param is_root_query: True - reload redis by root, do not check reload interval False - user reload, check reload interval z.[Redis reload request] Current user=%s data=%sNT)rurzX[Redis user data not found] Cloudlinux AccelerateWP daemon reloaded for user %s (uid=%d)zSCan't reload redis for user %(user)s. Last reload was less than %(sec)s seconds ago)usersec)rrOrzT[Redis user data found] Cloudlinux AccelerateWP daemon reloaded for user %s (uid=%d))rerxryrzr~r!rr}rrrr#rrr") rprrrrrurrrr#s r(_socket_user_redis_reloadz$WposDaemon._socket_user_redis_reload1s  $:>>sCC  Dc(mmUXYbUcUcddd   3 ;55c4l5[[K'+y{{K $  ABSU` a a a LL^_gil n n n F$5# M $B[B[\lBmBm )- &3/7@_&`&`bbK  ABSU` a a a F ^ n n55c4@@K'+y{{K $  ABSU` a a a KK^_gil n n n  n n n n n n n n n n n n n n n n n nsAFF FNaccountc dtdtdtfd}|p t}|r#|dt| fd|D}g}|D]~\}} |||d|d||d |d t |d d W#t $r|r|d |Y{wxYw|S)N handler_name version_idr+c2|dkrdSd|vrdS|rd|vrdS|S)Nfpmzphp-fpmz x-httpd-lsphplsapilsphpr@)rrs r(_castz1WposDaemon._php_get_vhost_versions.._cast`s?u$$ y J..w '\"9"9w r*z[PHP vhost info]: %sc4i|]\}}|dk||S)rr@)rArBrCrs r( z6WposDaemon._php_get_vhost_versions..ps8<<<*#u#J/7:::::r*rdisplay_version handler_typephp_version_idr)vhostrversionhandler documentrootz)Error on getting php version for %s, skip)r~r rzrGrrrr)rryphp_vhost_datar vhosts_datarOrBrCs` r(_php_get_vhost_versionsz"WposDaemon._php_get_vhost_versions]sr    %>(<(>(>  B KK.K0@0@ A A A  <<<< 8I8I8K8K<<OQWXXXXXr*cX|}tj||dS)z+ Get nginx status for user N)rrrrs r(_socket_user_nginx_statusz$WposDaemon._socket_user_nginx_statuss0 --//=>OQWXXXXXr*cX|}tj||dS)z2 Get apache2nginx status for user N)rrrrs r( _socket_user_apache2nginx_statusz+WposDaemon._socket_user_apache2nginx_statuss0 4466=>OQWXXXXXr*c ||t}d|d}n)#t$r}dt|d}Yd}~nd}~wwxYwt j||dS)N)ryrwrOrFz)Daemon cannot get vhosts data: %(reason)sr)rryrr~rr)rprr vhost_dataresponsers r(#_socket_user_php_get_vhost_versionsz.WposDaemon._socket_user_php_get_vhost_versionss 55gf5MMJ$"HH    Eq66HHHHHH  =>OQYZZZZZs$ A AA cRdtd}tj||dS)Nrwr)rrr)rprrs r('_socket_user_php_get_installed_versionsz2WposDaemon._socket_user_php_get_installed_versionss7.00   =>OQYZZZZZr*cddlm}|}d||t|ddd|d}t j||dS)Nr)get_server_wide_optionsrw)dns)keyls)rdomainfeature)rO upgrade_url) clwpos.utilsrget_upgrade_url_for_userrrr)rprrr#rserver_optionsrs r(_get_upgrade_linkzWposDaemon._get_upgrade_links 9888880022)BB!hh777:1=C   =>OQYZZZZZr*cXddlm}d||d}tj||dS)zI Get unique identifier which we use as user's auth token r)get_or_create_unique_identifierrw)rO unique_idN)clwpos.billingr*rr)rprrr*rs r(_get_unique_idzWposDaemon._get_unique_idsQ CBBBBB88BB   =>OQYZZZZZr*cbddlm}|\}}d||d}tj||dS)Nr)get_suites_status_from_licenserw)rOaccelerate_wp_premiumaccelerate_wp_cdn)r%r/rr)rprr/awp_premium_statusawp_cdn_statusrs r( _get_supported_suites_by_licensez+WposDaemon._get_supported_suites_by_licensesZ??????-K-K-M-M*N%7!/   =>OQYZZZZZr*c`ddlm}||d}d|d}tj||dS)Nr)is_user_owned_by_resellerT) force_as_rootrw)rOis_owned_by_reseller)r%r6rr)rprrr6r8rs r(_get_is_user_owned_by_resellerz)WposDaemon._get_is_user_owned_by_resellersZ::::::88QUVVV$8   =>OQYZZZZZr*cZddlm}|}d|d}tj||dS)Nr)is_wp2_environmentrw)rOis_wp2)clcommon.cpapir;rr)rprr;r<rs r(_get_is_wp2_environmentz"WposDaemon._get_is_wp2_environmentsQ555555##%%   =>OQYZZZZZr*cF ||\}}}}}|sdStdt||d|jkr||||dS|d|jkrL|dd}|dddk}|||||||dS|d|j kr| |dS|d|j kr| |dS|d|j kr||dS|d|jkr|||dS|d|jkr||dS|d|jkr-||||dd dS|d|jkr|||dS|d|jkr"|j||jdS|d|jkr|j|||dS|d|jkr2|j|||dd dS|d|jkr| |dS|d|j!kr|"||dS|d|j#kr|$|dSdS#tJ$rvt&d d  tOj(|d tSj)dYdS#tT$rt+dYYdSwxYwwxYw)z Process client's socket connection (Works in thread) :param client_socket_obj: Client socket connection NzIncome user request=%srrurrskip_last_reload_timeyesr# object_cachez"Socket connection processing errorTrzInternal daemon errorrz!Broken pipe during error response),rryrzr~ _DAEMON_GET_REDIS_STATUS_COMMANDr_DAEMON_RELOAD_COMMANDrxr$_DAEMON_GET_LITESPEED_STATUS_COMMANDr _DAEMON_GET_NGINX_STATUS_COMMANDr'_DAEMON_GET_APACHE2NGINX_STATUS_COMMANDr%DAEMON_PHP_GET_VHOST_VERSIONS_COMMANDr)DAEMON_PHP_GET_INSTALLED_VERSIONS_COMMANDrDAEMON_GET_UPGRADE_LINK_COMMANDr(DAEMON_GET_UNIQUE_ID_COMMANDr-DAEMON_SUITE_ALLOWED_CALLBACKrorXrgDAEMON_REGISTER_UPGRADE_ATTEMPTadd_pending_upgrade_task!DAEMON_GET_UPGRADE_ATTEMPT_STATUSget_upgrade_task_status&DAEMON_GET_SUPPORTED_SUITES_BY_LICENSEr4 DAEMON_IS_USER_OWNED_BY_RESELLERr9DAEMON_IS_WP2_ENVIRONMENTr>rrrrr}BrokenPipeErrorr) rpris_connection_validrrrrrurs r( _handle_client_socket_connectionz+WposDaemon._handle_client_socket_connections 8 D001BCC L h m&  KK0#l2C2C D D DI&$*OOO223DhPSTTTTTi(D,GGG+//EE '3'7'78OQU'V'VZ_'_$../@/7/2/'R'RTTTTTi(D,MMM##$5x@@@@@i(D,NNN#::;Ldl[[[[[i(D,PPP#<<=NP\^abbbbbi(D,RRR#;;?????KJ D D D   AD  Q Q Q DEFWd{KOKTKVKVZWZWXXXXXX" D D DBCCCCCCC D  DsL AL 3AL &L 8&L &L 'L 1&L  Process socket connections (works in thread) z4Cloudlinux AccelerateWP daemon socket thread startedrrNFr4)rargszFailed to start handler threadzSocket connection errorTrz4Cloudlinux AccelerateWP daemon socket thread stopped)ryrzrjselectrgacceptrrrrrnrmrx_MAX_CONNECTIONS_PER_UIDrlr7_release_uid_connectionr (_handle_client_socket_connection_trackedrrr9r-r)rpreadabler8 _sock_objectrrts r(rz&WposDaemon._process_socket_connections(s  JKKK& O#]DL>2r1EENHa ( O O O+7+>+>+@+@(%q!*>?PQQ$!!!)//111 !2gg6::3BBdFccc-33555$ggggggg<@;V;Z;Z[^`a;b;bef;f3C8 ggggggggggggggg  5==u=MM!44S999)//111 2"$*W):C(@BBB $222(()IJJJ2::<<<44S999)//11111 2 |OOO$$%>$NNNNNO9& O<  JKKKKKs H"A76H7BHB H":D H(&D HD H!D "AH,,FHA&H?HHH+H65H6c|j5|j|ddz }|dkr|j|dn ||j|<ddddS#1swxYwYdS)zYDecrement the per-UID active connection counter and remove the entry if it drops to zero.rrN)rnrmrxpop)rprcounts r(r\z"WposDaemon._release_uid_connectionMs  & 9 9/33C;;a?Ezz+//T::::38+C0  9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9sA A  A$'A$c |||j||dS#|j||wxYw)zn Wrapper around _handle_client_socket_connection that tracks per-UID active connection counts N)rVrlr9r\)rprrs r(r]z3WposDaemon._handle_client_socket_connection_trackedVs} .  1 12C D D D  & . . 0 0 0  ( ( - - - - -  & . . 0 0 0  ( ( - - - -s A0A7)rr)Fr^r)rrF)NNN)F__name__ __module__ __qualname____doc__rrDrCrErFrGrHrIrJrKrLrMrOrQrRrSrrr_REDIS_SOCKET_WAIT_TIMEOUTrkr[rdintboolr~rrrrrrrrIrrr staticmethoddictrrrr-rrrrrrrrrrrrrr(r-r4r9r>rVrr\r] __classcell__)rqs@r(rRrR`s 6%'9$+A('9$.G+,D)0L-&8##2 $<!&?#(C%-U*'D$ ;(,(/-1'$').(!" '$)%.(! '#"$!#"$ ;;;;;&2%2%s2%t2%cf2%rv2%2%2%2%h######J999$@@@*```.$$$ A A AD    a a a$>$>T$>$>$>$>Ra4aaa\a]t]]]\]ddddd\dK9V]K9uUY[^`hil`mU]^bUceiVjPkK9K9K9K9Zfv}fX[fbeffff,iSiTiiii7;?D *n*n6=*n,/*n'**n26*n14 *n 9= *n*n*n*nX###Z^###\#JYv}YYYYY6=YYYYY&-YYYY [V] []` [ [ [ [[[[[[[6=[[[[" [ [ [ [ [[&-[[[[[ [[[[[[[[[=D&-=DTX=D=D=D=D~#L#L#LJ93949999.&-.^a.fj........r*rR)N)?loggingr%rrHr}rJr-rYrrtypingrrr contextlibr collectionsr threadingrr r clwposr r8r=r r rrrrrrrrrrclwpos.daemon_redis_librrrrclwpos.socket_utilsrclwpos.daemon_baserclwpos.constantsrclwpos.cl_wpos_exceptionsr"clwpos.daemon_subscription_handlerrr getLoggerreryr)r2r:r~rPrRr@r*r(r|s  ((((((((((%%%%%%""""""4444444444+*****------444444999999IIIIII J{$M$M$M N N  8 $ $      D    66c6Xd38n-E6666~ .~ .~ .~ .~ .~ .~ .~ .~ .~ .r*