
    i                         d dl Z d dlmZ 	 d dlm Z d dlmZ n&# e$ r 	 d dlZd dlmZ n# e$ r dZdZY nw xY wY nw xY w	 d dl	m Z
 d dlmZ n# e$ r dZ
dZY nw xY wddlmZ ddlmZ  G d	 d
e          ZdS )    N)urlparse)asyncio)
RedisError)ValkeyError   )AsyncPubSubManager)parse_redis_sentinel_urlc                   J     e Zd ZdZdZ	 	 d fd	Zd Zd	 Zd
 Zd Z	d Z
 xZS )AsyncRedisManagera  Redis based client manager for asyncio servers.

    This class implements a Redis backend for event sharing across multiple
    processes.

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

        url = 'redis://hostname:port/0'
        server = socketio.AsyncServer(
            client_manager=socketio.AsyncRedisManager(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()``.
    aioredisredis://localhost:6379/0socketioFNc                     t           r)t          t           j        d          st          d          t	                                          ||||           || _        |pi | _        d| _        d | _	        d | _
        d S )Nfrom_urlz*Version 2 of aioredis package is required.)channel
write_onlyloggerjsonF)r   hasattrRedisRuntimeErrorsuper__init__	redis_urlredis_options	connectedredispubsub)selfurlr   r   r   r   r   	__class__s          G/usr/local/lib/python3.11/dist-packages/socketio/async_redis_manager.pyr   zAsyncRedisManager.__init__A   s     	MHNJ77	MKLLLZ" 	 	$ 	$ 	$*0b
    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   r   schemesplitlowerr   r   r   	aiovalkeyr   
ValueError)r   
parsed_urlr*   	error_msgs       r"   _get_redis_module_and_errorz-AsyncRedisManager._get_redis_module_and_errorN   s   dn--
"((a00399;;(((:#5" $: ; ; ; Z''*** K$7" $: ; ; ; k))V:#5$(;& (> ? ? ?
 %k11++=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 )N>   redis+sentinelvalkey+sentinelT)ignore_subscribe_messages)r1   r   r   r*   r	   r   updatesentinelSentinel
master_forr   r   r   r   r   r   )	r   module_r/   	sentinelsservice_nameconnection_kwargskwargsr7   s	            r"   _redis_connectz AsyncRedisManager._redis_connectk   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           	      D  K   |                                  \  }}t          ddd          D ]}	 | j        s|                                  | j                            | j        | j                            |                     d {V c S # |$ r}|dk    r@| 	                                
                    ddt          |          i           d| _        n?| 	                                
                    ddt          |          i           Y d }~ d S Y d }~d }~ww xY wd S )	Nr   r   z#Cannot publish to redis... retryingredis_exceptionextraFz$Cannot publish to redis... giving up)r1   ranger   r@   r   publishr   r   dumps_get_loggererrorstr)r   datar;   rJ   retries_leftexcs         r"   _publishzAsyncRedisManager._publish{   s     33555!!R,, 	 	L~ *'')))!Z//L$)//$"7"79 9 9 9 9 9 9 9 9 9 9   !##$$&&,,#0#c((; - = = = &+DNN$$&&,,$0#c((; - = = =
 EEEEEE #NNNN	 	s   AB		DA>DDc                  K   |                                  \  }}d}d}	 	 |s;|                                  | j                            | j                   d {V  d}| j                                        2 3 d {V }|W V  6 nw# |$ ro}|                                                     d| ddt          |          i           d}t          j
        |           d {V  |dz  }|d	k    rd	}Y d }~nd }~ww xY w)
Nr   FTz)Cannot receive from redis... retrying in z secsrC   rD      <   )r1   r@   r   	subscriber   listenrI   rJ   rK   r   sleep)r   r;   rJ   retry_sleep
subscribedmessagerN   s          r"   _redis_listen_with_retriesz,AsyncRedisManager._redis_listen_with_retries   s     33555
	%%! $'')))+//========="#K%)[%7%7%9%9 " " " " " " "'!MMMMM &:%9 	% 	% 	%  ""(( *?,7*? *? *? 1B3s88/L ) N N N #
mK000000000q ##"$K	%	%s%   AB 6B<B C9
A%C44C9c                  K   | j                             d          }|                                 2 3 d {V }|d         |k    r|d         dk    rd|v r|d         W V  /6 | j                            | j                    d {V  d S )Nzutf-8r   typerX   rL   )r   encoderY   r   unsubscribe)r   r   rX   s      r"   _listenzAsyncRedisManager._listen   s      ,%%g..!<<>> 	& 	& 	& 	& 	& 	& 	&'y!W,,FOy00Vw5F5Ffo%%%% ? k%%dl33333333333s   A )r   r   FNNN)__name__
__module____qualname____doc__namer   r1   r@   rO   rY   r^   __classcell__)r!   s   @r"   r   r      s        # #H D?IIM     $ $ $:     .% % %.4 4 4 4 4 4 4r#   r   )r   urllib.parser   r   r   redis.exceptionsr   ImportErroraioredis.exceptionsr'   r-   valkey.exceptionsr   async_pubsub_managerr   redis_managerr	   r    r#   r"   <module>rm      so    ! ! ! ! ! !	))))))+++++++   2222222   


	++++++-------   IKKK 5 4 4 4 4 4 3 3 3 3 3 3U4 U4 U4 U4 U4* U4 U4 U4 U4 U4s6    <
*<	6<6<< A 	AA