
    i"                         d dl Z d dlZd dlmZ 	 d dlZd dlmZ n# e$ r dZdZY nw xY w	 d dlZd dl	m
Z
 n# e$ r dZdZ
Y nw xY wddlmZ  e j        d          Zd Z G d	 d
e          ZdS )    N)urlparse)
RedisError)ValkeyError   )PubSubManagersocketioc                    t          |           }|j        dvrt          d          g }|j                            d          d                             d          D ]?}|                    dd          \  }}|                    |t          |          f           @i }|j        r
|j        |d<   |j	        r
|j	        |d	<   d
}|j
        rx|j
                            d          }t          |          dk    r$|d         dk    rt          |d                   |d<   t          |          dk    r|d         dk    r|d         }|||fS )z}Parse a Redis Sentinel URL with the format:
    redis+sentinel://[:password]@host1:port1,host2:port2,.../db/service_name
       redis+sentinelvalkey+sentinelzInvalid Redis Sentinel URL@,:r   usernamepasswordN/    db   )r   scheme
ValueErrornetlocsplitrsplitappendintr   r   pathlen)	url
parsed_url	sentinels	host_porthostportkwargsservice_namepartss	            A/usr/local/lib/python3.11/dist-packages/socketio/redis_manager.pyparse_redis_sentinel_urlr+      sX    #J EEE5666I&,,S11"5;;C@@ , ,	%%c1--
d$D		*++++F 1'0z 1'0zL $%%c**u::??uQx2~~uQx==F4Lu::??uQx2~~ 8LlF**    c                   T     e Zd ZdZdZ	 	 d fd	Z fdZd	 Zd
 Zd Z	d Z
d Z xZS )RedisManagera6  Redis based client manager.

    This class implements a Redis backend for event sharing across multiple
    processes. Only kept here as one more example of how to build a custom
    backend, since the kombu backend is perfectly adequate to support a Redis
    message queue.

    To use a Redis backend, initialize the :class:`Server` instance as
    follows::

        url = 'redis://hostname:port/0'
        server = socketio.Server(client_manager=socketio.RedisManager(url))

    :param url: The connection URL for the Redis server. For a default Redis
                store running on the same host, use ``redis://``.  To use a
                TLS connection, use ``rediss://``. To use Redis Sentinel, use
                ``redis+sentinel://`` with a comma-separated list of hosts
                and the service name after the db in the URL path. Example:
                ``redis+sentinel://user:pw@host1:1234,host2:2345/0/myredis``.
    :param channel: The channel name on which the server sends and receives
                    notifications. Must be the same in all the servers.
    :param write_only: If set to ``True``, only initialize to emit events. The
                       default of ``False`` initializes the class for emitting
                       and receiving. A write-only instance can be used
                       independently of the server to emit to clients from an
                       external process.
    :param logger: a custom logger to log it. If not given, the server logger
                   is used.
    :param json: An alternative JSON module to use for encoding and decoding
                 packets. Custom json modules must have ``dumps`` and ``loads``
                 functions that are compatible with the standard library
                 versions. This setting is only used when ``write_only`` is set
                 to ``True``. Otherwise the JSON module configured in the
                 server is used.
    :param redis_options: additional keyword arguments to be passed to
                          ``Redis.from_url()`` or ``Sentinel()``.
    redisredis://localhost:6379/0r   FNc                     t                                          ||||           || _        |pi | _        d| _        d | _        d | _        d S )N)channel
write_onlyloggerjsonF)super__init__	redis_urlredis_options	connectedr/   pubsub)selfr!   r2   r3   r4   r5   r9   	__class__s          r*   r7   zRedisManager.__init__Z   sZ    Z" 	 	$ 	$ 	$*0b
r,   c                 
   t                                                       d}| j        j        dk    rddlm}  |d          }nd| j        j        v rddlm}  |d          }|st          d| j        j        z             d S )	NTeventletr   )is_monkey_patchedsocketgevent)is_module_patchedz<Redis requires a monkey patched socket library to work with )	r6   
initializeserver
async_modeeventlet.patcherr@   gevent.monkeyrC   RuntimeError)r<   monkey_patchedr@   rC   r=   s       r*   rD   zRedisManager.initialized   s    ;!Z//::::::..x88NN///777777..x88N 	2+012 2 2	2 	2r,   c                    t          | j                  }|j                            dd          d                                         }|dv r+t
          t          t          d          t
          t          fS |dv r+t          t          t          d          t          t          fS |dk    rGt
          t          +t          t          t          d	          t          t          fS t
          t          fS d
| }t          |          )N+r   r   )r/   redisszLRedis package is not installed (Run "pip install redis" in your virtualenv).)valkeyvalkeyszNValkey package is not installed (Run "pip install valkey" in your virtualenv).unixzdRedis package is not installed (Run "pip install redis" or "pip install valkey" in your virtualenv).zUnsupported Redis URL scheme: )r   r8   r   r   lowerr/   r   rI   rN   r   r   )r<   r"   r   	error_msgs       r*   _get_redis_module_and_errorz(RedisManager._get_redis_module_and_errors   s   dn--
"((a00399;;(((}
 2" $: ; ; ; *$$***~!4" $: ; ; ; ;&&V}
 2>[%8& (> ? ? ?
 ";..j((=V==	###r,   c                    |                                  \  }}t          | j                  }|j        dv rit	          | j                  \  }}}| j        }|                    |            |j        j        |fi |}|	                    |p| j
                  | _        n" |j        j        | j        fi | j        | _        | j                            d          | _        d| _        d S )Nr
   T)ignore_subscribe_messages)rS   r   r8   r   r+   r9   updatesentinelSentinel
master_forr2   r/   Redisfrom_urlr;   r:   )	r<   module_r"   r#   r(   connection_kwargsr'   rW   s	            r*   _redis_connectzRedisManager._redis_connect   s    4466	dn--
 EEE(88 7I|%6'FMM+,,,/v/	DDVDDH!,,\-IT\JJDJJ..t~ E E151CE EDJj''$'GGr,   c           	          |                                  \  }}t          ddd          D ]}	 | j        s|                                  | j                            | j        | j                            |                    c S # |$ ru}|dk    r3t          
                    ddt          |          i           d| _        n2t          
                    ddt          |          i           Y d }~ d S Y d }~d }~ww xY wd S )	Nr   r   r   z#Cannot publish to redis... retryingredis_exceptionextraFz$Cannot publish to redis... giving up)rS   ranger:   r_   r/   publishr2   r5   dumpsr4   errorstr)r<   datar]   rg   retries_leftexcs         r*   _publishzRedisManager._publish   s6   33555!!R,, 	 	L~ *'')))z))$,	8M8MNNNNN   !##LL=0#c((; !    &+DNNLL>0#c((; !    EEEEEE #NNNN	 	s   ABC;A$C66C;c              #     K   |                                  \  }}d}d}	 	 |s5|                                  | j                            | j                   d}| j                                        E d {V  nd# |$ r\}t                              d| ddt          |          i           d}t          j
        |           |dz  }|d	k    rd	}Y d }~nd }~ww xY w)
Nr   FTz)Cannot receive from redis... retrying in z secsra   rb   r   <   )rS   r_   r;   	subscriber2   listenr4   rg   rh   timesleep)r<   r]   rg   retry_sleep
subscribedrk   s         r*   _redis_listen_with_retriesz'RedisManager._redis_listen_with_retries   s,     33555
	%%! $'')))K))$,777"#K;--////////// % % % ?,7? ? ?$5s3xx#@  B B B #

;'''q ##"$K%	%s   AA7 7C<ACCc              #      K   | j                             d          }|                                 D ](}|d         |k    r|d         dk    rd|v r
|d         V  )| j                            | j                    d S )Nzutf-8r2   typemessageri   )r2   encoderu   r;   unsubscribe)r<   r2   rx   s      r*   _listenzRedisManager._listen   s      ,%%g..6688 	& 	&Gy!W,,FOy00Vw5F5Ffo%%%-----r,   )r0   r   FNNN)__name__
__module____qualname____doc__namer7   rD   rS   r_   rl   ru   r{   __classcell__)r=   s   @r*   r.   r.   2   s        $ $J D?IIM     2 2 2 2 2$ $ $:     *% % %*. . . . . . .r,   r.   )loggingrq   urllib.parser   r/   redis.exceptionsr   ImportErrorrN   valkey.exceptionsr   pubsub_managerr   	getLoggerr4   r+   r.    r,   r*   <module>r      s4     ! ! ! ! ! !LLL+++++++   EJJJMMM-------   FKKK * ) ) ) ) )		:	&	&+ + +4^. ^. ^. ^. ^.= ^. ^. ^. ^. ^.s   
 	''
6 	AA