
    `f/                         d dl Z d dlZd dlZd dlZd dlZd dlm Z ddlmZm	Z	m
Z
mZmZ  ej        e          Zd Z G d d          Z G d d	          Z G d
 d          ZdS )    N)asyncio   )_close_redis_consistent_hash_wrap_closecreate_pooldecode_hostsc                 f   K   |                                  } t          ||          |i | d {V S N)
_get_layergetattr)objnameargskwargslayers        G/var/www/html/env/lib/python3.11/site-packages/channels_redis/pubsub.py_async_proxyr      sH       NNE%%%t6v666666666    c                   .    e Zd ZddZd Zd Zd Zd ZdS )	RedisPubSubChannelLayerreturnNc                 0    || _         || _        i | _        d S r   )_args_kwargs_layers)selfr   r   s      r   __init__z RedisPubSubChannelLayer.__init__   s    
r   c                     |dv rt          j        t          | |          S t          |                                 |          S )N)new_channelsendreceive	group_addgroup_discard
group_sendflush)	functoolspartialr   r   r   )r   r   s     r   __getattr__z#RedisPubSubChannelLayer.__getattr__!   sE     
 
 
 $\4>>>4??,,d333r   c                 *    t          j        |          S )z6
        Serializes message to a byte string.
        )msgpackpackbr   messages     r   	serializez!RedisPubSubChannelLayer.serialize/   s     }W%%%r   c                 *    t          j        |          S )z2
        Deserializes from a byte string.
        )r+   unpackbr-   s     r   deserializez#RedisPubSubChannelLayer.deserialize5   s     w'''r   c                     t          j                    }	 | j        |         }nD# t          $ r7 t	          | j        i | j        d| i}|| j        |<   t          | |           Y nw xY w|S )Nchannel_layer)r   get_running_loopr   KeyErrorRedisPubSubLoopLayerr   r   r   )r   loopr   s      r   r   z"RedisPubSubChannelLayer._get_layer;   s    '))		$L&EE 	$ 	$ 	$(,  #  E
 "'DLd#####	$ s   # >A$#A$)r   N)__name__
__module____qualname__r   r)   r/   r2   r    r   r   r   r      sd           
4 4 4& & &( ( (    r   r   c                   j    e Zd ZdZ	 	 	 	 	 ddZd Zd Zd Zdd	gZd
 Z	ddZ
d Zd Zd Zd Zd ZdS )r7   z@
    Channel Layer that uses Redis's pub/sub functionality.
    Nasgic                      | _         | _        | _        | _        i  _        i  _         fdt          |          D              _        d S )Nc                 0    g | ]}t          |          S r<   )RedisSingleShardConnection).0hostr   s     r   
<listcomp>z1RedisPubSubLoopLayer.__init__.<locals>.<listcomp>i   s1     
 
 
7;&tT22
 
 
r   )prefixon_disconnecton_reconnectr4   channelsgroupsr	   _shards)r   hostsrE   rF   rG   r4   r   s   `      r   r   zRedisPubSubLoopLayer.__init__Q   sl     *(*  
 
 
 
?KE?R?R
 
 
r   c                 \    | j         t          |t          | j                                      S )zV
        Return the shard that is used exclusively for this channel or group.
        )rJ   r   len)r   channel_or_group_names     r   
_get_shardzRedisPubSubLoopLayer._get_shardm   s'     |,-BCDUDUVVWWr   c                     | j          d| S )a\  
        Return the channel name used by a group.
        Includes '__group__' in the returned
        string so that these names are distinguished
        from those returned by `new_channel()`.
        Technically collisions are possible, but it
        takes what I believe is intentional abuse in
        order to have colliding names.
        	__group__)rE   )r   groups     r   _get_group_channel_namez,RedisPubSubLoopLayer._get_group_channel_names   s     +/////r   c                    K   t          j                    | j        |<   |                     |          }|                    |           d {V  d S r   )r   QueuerH   rO   	subscribe)r   channelshards      r   _subscribe_to_channelz*RedisPubSubLoopLayer._subscribe_to_channel   sS      !(g((oog&&&&&&&&&&&r   rI   r&   c                    K   |                      |          }|                    || j                            |                     d{V  dS )zF
        Send a message onto a (general or specific) channel.
        N)rO   publishr4   r/   )r   rW   r.   rX   s       r   r!   zRedisPubSubLoopLayer.send   sV       ((mmGT%7%A%A'%J%JKKKKKKKKKKKr   	specific.c                    K   | j          | t          j                    j         }|                     |           d{V  |S )zy
        Returns a new channel name that can be used by a consumer in our
        process as a specific channel.
        N)rE   uuiduuid4hexrY   )r   rE   rW   s      r   r    z RedisPubSubLoopLayer.new_channel   sS      
 [<&<$*,,*:<<((111111111r   c                   K   || j         vr|                     |           d{V  | j         |         }	 |                                 d{V }n# t          j        t          j        t          f$ ro || j         v rd| j         |= 	 |                     |          }|                    |           d{V  n*# t          $ r t                              d           Y nw xY w w xY w| j                            |          S )z
        Receive the first message that arrives on the channel.
        If more than one coroutine waits on the same channel, a random one
        of the waiting coroutines will get the result.
        Nz/Unexpected exception while cleaning-up channel:)rH   rY   getr   CancelledErrorTimeoutErrorGeneratorExitrO   unsubscribeBaseExceptionlogger	exceptionr4   r2   )r   rW   qr.   rX   s        r   r"   zRedisPubSubLoopLayer.receive   s@      $-'',,W555555555M'"	EEGGmmmmmmGG&(<mL 	 	 	 $-''M'*X OOG44E++G4444444444$ X X X$$%VWWWWWX #	& !--g666s/   A 2C 0B43C 4$CC CC c                 p  K   || j         vr t          dt          |           d          |                     |          }|| j        vrt                      | j        |<   | j        |         }||vr|                    |           |                     |          }|                    |           d{V  dS )z3
        Adds the channel name to a group.
        zYou can only call group_add() on channels that exist in-process.
Consumers are encouraged to use the common pattern:
   self.channel_layer.group_add(z, self.channel_name)N)	rH   RuntimeErrorreprrS   rI   setaddrO   rV   r   rR   rW   group_channelgroup_channelsrX   s         r   r#   zRedisPubSubLoopLayer.group_add   s       $-''U37;;U U U  
 44U;;++),DK&]3.((w'''..oom,,,,,,,,,,,r   c                 R  K   |                      |          }| j                            |t                                }||vrdS |                    |           t          |          dk    r:| j        |= |                     |          }|                    |           d{V  dS dS )zy
        Removes the channel from a group if it is in the group;
        does nothing otherwise (does not error)
        Nr   )rS   rI   rb   rn   removerM   rO   rf   rp   s         r   r$   z"RedisPubSubLoopLayer.group_discard   s      
 44U;;>>.((Fg&&&~!##M*OOM22E##M22222222222 $#r   c                    K   |                      |          }|                     |          }|                    || j                            |                     d{V  dS )zC
        Send the message to all subscribers of the group.
        N)rS   rO   r[   r4   r/   )r   rR   r.   rq   rX   s        r   r%   zRedisPubSubLoopLayer.group_send   si       44U;;..mmM4+=+G+G+P+PQQQQQQQQQQQr   c                 n   K   i | _         i | _        | j        D ]}|                                 d{V  dS )z
        Flush the layer, making it like new. It can continue to be used as if it
        was just created. This also closes connections, serving as a clean-up
        method; connections will be re-opened if you continue using this layer.
        N)rH   rI   rJ   r&   )r   rX   s     r   r&   zRedisPubSubLoopLayer.flush   sT       \ 	  	 E++--	  	 r   )Nr>   NNN)r\   )r9   r:   r;   __doc__r   rO   rS   rY   
extensionsr!   r    r"   r#   r$   r%   r&   r<   r   r   r7   r7   L   s          
 
 
 
8X X X
0 
0 
0' ' '
 G$JL L L   7 7 7J- - -&3 3 3 R R R	  	  	  	  	 r   r7   c                   D    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
S )rA   c                     || _         || _        t                      | _        t	          j                    | _        d | _        d | _        d | _	        d S r   )
rC   r4   rn   _subscribed_tor   Lock_lock_redis_pubsub_receive_task)r   rC   r4   s      r   r   z#RedisSingleShardConnection.__init__   sF    	*!ee\^^
!r   c                    K   | j         4 d {V  |                                  | j                            ||           d {V  d d d           d {V  d S # 1 d {V swxY w Y   d S r   )r}   _ensure_redisr~   r[   )r   rW   r.   s      r   r[   z"RedisSingleShardConnection.publish  s     : 	8 	8 	8 	8 	8 	8 	8 	8   +%%gw777777777	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s   6A
A#&A#c                 D  K   | j         4 d {V  || j        vrb|                                  |                                  | j                            |           d {V  | j                            |           d d d           d {V  d S # 1 d {V swxY w Y   d S r   )r}   r{   r   _ensure_receiverr   rV   ro   r   rW   s     r   rV   z$RedisSingleShardConnection.subscribe	  s=     : 	1 	1 	1 	1 	1 	1 	1 	1d111""$$$%%'''l,,W555555555#''000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1   A,B
BBc                 D  K   | j         4 d {V  || j        v rb|                                  |                                  | j                            |           d {V  | j                            |           d d d           d {V  d S # 1 d {V swxY w Y   d S r   )r}   r{   r   r   r   rf   rt   r   s     r   rf   z&RedisSingleShardConnection.unsubscribe  s=     : 	4 	4 	4 	4 	4 	4 	4 	4$---""$$$%%'''l..w777777777#**7333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4r   c                   K   | j         4 d {V  | j        D| j                                         	 | j         d {V  n# t          j        $ r Y nw xY wd | _        | j        (t          | j                   d {V  d | _        d | _        t                      | _	        d d d           d {V  d S # 1 d {V swxY w Y   d S r   )
r}   r   cancelr   rc   r~   r   r   rn   r{   r   s    r   r&   z RedisSingleShardConnection.flush  s~     : 	( 	( 	( 	( 	( 	( 	( 	(!-"))+++,,,,,,,,,-   D%)"{& #4;/////////"#"%%%D	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(s4   !B1A B1 AB1AAB11
B;>B;c                   K   	 	 | j         rD| j         j        r8| j                             dd           d {V }|                     |           nt	          j        d           d {V  ne# t          j        t          j        t          f$ r  t          $ r7 t                              d           t	          j        d           d {V  Y nw xY w)NTg?)ignore_subscribe_messagestimeoutz$Unexpected exception in receive taskr   )r   
subscribedget_message_receive_messager   sleeprc   rd   re   rg   rh   ri   r-   s     r   _do_receivingz(RedisSingleShardConnection._do_receiving+  s&     	''< -DL$; -$(L$<$<26 %= % %      G ))'2222!-,,,,,,,,,&$   
   ' ' '  !GHHHmA&&&&&&&&&&&'	's   A%A+ +ACCc                    ||d         }|d         }t          |t                    r|                                }|| j        j        v r'| j        j        |                             |           d S || j        j        v rJ| j        j        |         D ]9}|| j        j        v r%| j        j        |                             |           6d S d S d S )NrW   data)
isinstancebytesdecoder4   rH   
put_nowaitrI   )r   r.   r   r   channel_names        r   r   z+RedisSingleShardConnection._receive_message?  s    9%D6?D$&& %{{}}t)222"+D1<<TBBBBB+222$($6$=d$C S SL#t'9'BBB*3LALLTRRR  32S Sr   c                     | j         Nt          | j                  }t          j        |          | _         | j                                         | _        d S d S )N)connection_pool)r~   r   rC   aioredisRedispubsubr   )r   pools     r   r   z(RedisSingleShardConnection._ensure_redisL  sN    ;ty))D".>>>DK;--//DLLL r   c                 n    | j         -t          j        |                                           | _         d S d S r   )r   r   ensure_futurer   r   s    r   r   z+RedisSingleShardConnection._ensure_receiverR  s8    %!(!6t7I7I7K7K!L!LD &%r   N)r9   r:   r;   r   r[   rV   rf   r&   r   r   r   r   r<   r   r   rA   rA      s        " " "8 8 8
1 1 14 4 4( ( ($' ' '(S S S0 0 0M M M M Mr   rA   )r   r'   loggingr^   r+   redisr   utilsr   r   r   r   r	   	getLoggerr9   rh   r   r   r7   rA   r<   r   r   <module>r      sP           % % % % % %              
	8	$	$7 7 7. . . . . . . .bk  k  k  k  k  k  k  k \ZM ZM ZM ZM ZM ZM ZM ZM ZM ZMr   