
    hՖ                         d dl Z d dlZd dlmZ d dlZd dlmZ d dlmZ	 d dl
mZ d dlmZmZmZ d dlmZmZ d dlmZmZ d dlmZ d	Zdd
ZddZ G d de      Z G d d	e      ZddZy)    N)partial)ObservableMixin)	parse_url)ComponentConfigSubscribeOptionsRegisterOptions)SessionNotReadyApplicationError)create_authenticatorIAuthenticator)SERID_TO_SER	Componentc                    |r	 ||        nt        | t              st        d      t        | t              rd| vrt        d      | d   dvrt        dj                  | d               | j	                         D ]   }|dvst        dj                  |             | d   dk(  rKd	D ]   }|| vst        d
j                  |             dD ]   }|| v st        dj                  |             y| d   dk(  rKdD ]   }|| vst        dj                  |             dD ]   }|| v st        dj                  |             yJ d       y)z9
    Check a WAMP connecting endpoint configuration.
    z'endpoint' must be a dicttypez)'type' required in endpoint configuration)tcpunixzinvalid type "{}" in endpoint)r   hostportpathtlstimeoutversionz*Invalid key '{}' in endpoint configurationr   r   r   z&'{}' required in 'tcp' endpoint config)r   z''{}' not valid in 'tcp' endpoint configr   z('{}' required for 'unix' endpoint config)r   r   r   z('{}' not valid in 'unix' endpoint configshould not arrive hereN)
isinstancedict
ValueErrorformatkeys)endpointcheck_native_endpointks      S/var/www/Befach/backend/env/lib/python3.12/site-packages/autobahn/wamp/component.py_validate_endpointr$   1   s    h'$''
 	
 (D! !HIIF?2<CCHVDTUVVAUU @GGJ  ! Fu$%H$$@GGJ  &
 =$AHHK  
 f'H$$BII!L  
 -=$BII!L  - 3225M "    c                    t        |      t        k7  r#t        dj                  t        |                  g d}|j	                         D ]   }||vst        dj                  |             d}d|v r*|d   dvrt        dj                  |d               |d   }nd|d<   d|v r|dk7  rt        d	      |j                  dd
      }|X|j	                         D ]   }|dvst        dj                  |             dD ]   }||vst        dj                  |             t               }d|v r8|d   }t        |t              s#t        dj                  t        |                  |j                  d      }|dk(  rAdD ]   }	|	|vst        dj                  |	             d|vrt        |d         \  }
}}}}}d|||
d}n|d   }t        ||       d|v rt        d      d|v rt        |d   t        t        f      st        d      t        |d   D cg c]  }t        |t        t        f       c}      st        d      t        j                         }|d   D ]G  }||vst        dj                  |dj                  |D cg c]  }t!        |       c}                   |j                  dddg      }n|dk(  rd|vrm|d   j#                  d       rt%        |d         \  }}}n4|d   j#                  d!      rt        |d         \  }}}}}}n
t'               |d"k(  rd"|d#}nd||d$}n|d   }d|v rt        d%      |t        d&      d|v r+t        |d   t        t        f      st        d'      |d   g}ndg}nJ d(       i }d)D ]  }	|	|v s||	   ||	<    t)        | f||j                  dd
      |||||d*|S c c}w c c}w )+a   
    Internal helper to insert defaults and create _Transport instances.

    :param transport: a (possibly valid) transport configuration
    :type transport: dict

    :returns: a _Transport instance

    :raises: ValueError on invalid configuration
    z<invalid type {} for transport configuration - must be a dict)r   urlr    
serializerserializersoptionsmax_retriesmax_retry_delayinitial_retry_delayretry_delay_growthretry_delay_jitterproxyheadersz&'{}' is not a valid configuration item	websocketr   )r2   	rawsocketzInvalid transport type {}r0   z3proxy= only supported for type=websocket transportsNr   z Unknown key '{}' in proxy configzProxy config requires '{}'r*   zoptions must be a dict, not {}r1   )r'   zTransport requires '{}' keyr    r'   r   )r   r   r   r   r(   z5'serializer' is only for rawsocket; use 'serializers'r)   z''serializers' must be a list of stringsz-Invalid serializer '{}' (expected one of: {})z, cborjsonr3   rswsr   )r   r   )r   r   r   z5'serializers' is only for websocket; use 'serializer'z/'headers' not supported for rawsocket transportz'serializer' must be a stringr   )r+   r,   r-   r.   r/   )kindr'   r    r)   r0   r*   r1   )r   r   r   r   r   getformaTr   parse_ws_urlr$   listtupleallstrr   joinrepr
startswithparse_rs_urlRuntimeError
_Transport)index	transportr!   valid_transport_keysr"   r8   r0   r*   r1   key	is_securer   r   resourcer   paramsendpoint_configsvalid_serializersserialserializer_configisSecurekws                          r#   _create_transportrT   j   s    I$W^^_cdm_nopp
 ^^((8??B   DV$>>8??	&@QRSS '	&) 3A
 	
 MM'4(EA(( 6==a@  
 "A~ 077:  " fGII&'4(077WF  mmI&G{C)# !>!E!Ec!JKK 
 Y&<HSXIY<Z9ItT8T6 	O (
3O0EF9$TUUI%i6uF !JKK&}57 q3*-7 8 !!JKK , 1 1 3#M2!22$GNN" II8I&J1tAw&JK  3 &MM-&&9IJ		Y&**40'3Ie4D'E$$5!,,T2?KIV[L\?]<$hf"n$v~ # # "  # (
3OI%TUUNOO9$i5SzB !@AA!*<!8 9!' 	/..u	B<)nBsG<
 
MM%& %
 
 
y7 'Ks   O	Oc                   F    e Zd ZdZ	 	 	 	 	 	 	 	 d	dZd Zd Zd Zd Zd Z	y)
rE   z@
    Thin-wrapper for WAMP transports used by a Connection.
    Nc                 P   |
t               }|| _        || _        || _        || _        || _        || _        || _        | j                  dk(  rt        |      dk7  rt        d      || _
        || _        || _        |	| _        |
| _        || _        d| _        | j#                          y)z	
        Nr3      z5'rawsocket' transport requires exactly one serializerF)r   idxr   r'   r    r*   r1   r)   lenr   r+   r,   r-   r.   r/   r0   _permanent_failurereset)selfrX   r8   r'   r    r)   r+   r,   r-   r.   r/   r0   r*   r1   s                 r#   __init__z_Transport.__init__  s     ?fG	 &99#K(8A(=G  '.#6 "4"4
 #(

r%   c                 P    d| _         d| _        d| _        | j                  | _        y)zP
        set connection failure rates and retry-delay to initial values
        r   N)connect_attemptsconnect_sucessesconnect_failuresr-   retry_delayr\   s    r#   r[   z_Transport.reset5  s*     !" ! !33r%   c                     d| _         y)z
        Mark this transport as failed, meaning we won't try to connect to
        it any longer (that is: can_reconnect() will always return
        False afer calling this).
        TN)rZ   rc   s    r#   failedz_Transport.failed>  s     #'r%   c                 t    | j                   ry| j                  dk(  ry| j                  | j                  dz   k  S )NFTrW   )rZ   r+   r_   rc   s    r#   can_reconnectz_Transport.can_reconnectF  s;    ""r!$$t'7'7!';;;r%   c                    | j                   dk(  ry| j                  dk7  r'| j                   | j                  dz   k\  rt        d      | j                  | j                  z  | _        t        j                  | j                  | j                  | j                  z        | _        | j                  | j                  kD  r| j                  | _        | j                  S )Nr   rg   rW   zmax reconnects reached)	r_   r+   rD   rb   r.   randomnormalvariater/   r,   rc   s    r#   
next_delayz_Transport.next_delayM  s      A%#(=(=AQAQTUAU(U788#//$2I2IID%33D4D4DdFVFVY]YpYpFpqD$"6"66#'#7#7 ###r%   c                 ~    t        | j                  t              r| j                  d   S t        | j                        S )zF
        returns a human-readable description of the endpoint
        r   )r   r    r   rA   rc   s    r#   describe_endpointz_Transport.describe_endpointZ  s0     dmmT*==((DMM""r%   )rg   i,        ?ro   g?NNN)
__name__
__module____qualname____doc__r]   r[   re   rh   rl   rn    r%   r#   rE   rE     s@    
  !$%($'$'&P4'<$#r%   rE   c                   p    e Zd ZdZdZ	 ddZddZ	 	 ddZd ZddZ	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zy)r   z
    A WAMP application component. A component holds configuration for
    (and knows how to create) transports and sessions.
    Nc                 F     t        t              sJ  fd}|S )a[  
        A decorator as a shortcut for subscribing during on-join

        For example::

            @component.subscribe(
                "some.topic",
                options=SubscribeOptions(match='prefix'),
            )
            def topic(*args, **kw):
                print("some.topic({}, {}): event received".format(args, kw))
        c                 >      fd}j                  d|        S )Nc                 .    | j                        S )N)topicr*   check_types)	subscribe)sessiondetailsrz   fnr*   ry   s     r#   do_subscriptionz?Component.subscribe.<locals>.decorator.<locals>.do_subscription  s    ((5'Wb(ccr%   r@   on)r~   r   rz   r*   r\   ry   s   ` r#   	decoratorz&Component.subscribe.<locals>.decorator  s    dGGFO,Ir%   )r   r   )r\   ry   r*   rz   r   s   ```` r#   r{   zComponent.subscriber  s'     *W6F"GGG	 r%   c                 F     t        t              sJ  fd}|S )aZ  
        A decorator as a shortcut for registering during on-join

        For example::

            @component.register(
                "com.example.add",
                options=RegisterOptions(invoke='roundrobin'),
            )
            def add(*args, **kw):
                print("add({}, {}): event received".format(args, kw))
        c                 >      fd}j                  d|        S )Nc                 .    | j                        S )N)	procedurer*   rz   )register)r|   r}   rz   r~   r*   uris     r#   do_registrationz>Component.register.<locals>.decorator.<locals>.do_registration  s    ''c7Xc'ddr%   r@   r   )r~   r   rz   r*   r\   r   s   ` r#   r   z%Component.register.<locals>.decorator  s    eGGFO,Ir%   )r   r   )r\   r   r*   rz   r   s   ```` r#   r   zComponent.register  s&     *Wo"FFF	 r%   c	                 Z   | j                  g d       |t        |      st        d      || _        |t        |      st        d      || _        |d}t        |t        t        f      r|}	d|	d}
|
g}nt        |t              r|g}g | _        t        |      D ]O  \  }}
t        |
      t        k(  rd|
d}n|
}| j                  j                  t        ||| j                               Q |xs i | _        |r|| _        || _        || _        d| _        d| _        d| _        d| _        y)	a  
        :param main: After a transport has been connected and a session
            has been established and joined to a realm, this (async)
            procedure will be run until it finishes -- which signals that
            the component has run to completion. In this case, it usually
            doesn't make sense to use the ``on_*`` kwargs. If you do not
            pass a main() procedure, the session will not be closed
            (unless you arrange for .leave() to be called).

        :type main: callable taking two args ``reactor`` and ``ISession``

        :param transports: Transport configurations for creating
            transports. Each transport can be a WAMP URL, or a dict
            containing the following configuration keys:

                - ``type`` (optional): ``websocket`` (default) or ``rawsocket``
                - ``url``: the router URL
                - ``endpoint`` (optional, derived from URL if not provided):
                    - ``type``: "tcp" or "unix"
                    - ``host``, ``port``: only for TCP
                    - ``path``: only for unix
                    - ``timeout``: in seconds
                    - ``tls``: ``True`` or (under Twisted) an
                      ``twisted.internet.ssl.IOpenSSLClientComponentCreator``
                      instance (such as returned from
                      ``twisted.internet.ssl.optionsForClientTLS``) or
                      ``CertificateOptions`` instance.
                - ``max_retries``: Maximum number of reconnection attempts. Unlimited if set to -1.
                - ``initial_retry_delay``: Initial delay for reconnection attempt in seconds (Default: 1.0s).
                - ``max_retry_delay``: Maximum delay for reconnection attempts in seconds (Default: 60s).
                - ``retry_delay_growth``: The growth factor applied to the retry delay between reconnection attempts (Default 1.5).
                - ``retry_delay_jitter``: A 0-argument callable that introduces nose into the delay. (Default random.random)
                - ``serializer`` (only for raw socket): Specify an accepted serializer (e.g. 'json', 'msgpack', 'cbor', 'ubjson', 'flatbuffers')
                - ``serializers``: Specify list of accepted serializers
                - ``options``: tbd
                - ``proxy``: tbd

        :type transports: None or str or list

        :param realm: the realm to join
        :type realm: str

        :param authentication: configuration of authenticators
        :type authentication: dict

        :param session_factory: if None, ``ApplicationSession`` is
            used, otherwise a callable taking a single ``config`` argument
            that is used to create a new `ApplicationSession` instance.

        :param is_fatal: a callable taking a single argument, an
            ``Exception`` instance. The callable should return ``True`` if
            this error is "fatal", meaning we should not try connecting to
            the current transport again. The default behavior (on None) is
            to always return ``False``
        )startconnectr@   readyleave
disconnectconnectfailureNz%"is_fatal" must be a callable or Nonez""main" must be a callable if givenzws://127.0.0.1:8080/wsr2   )r   r'   F)set_valid_eventscallabler   	_is_fatal_entryr   r?   r   _transports	enumerater   appendrT   _check_native_endpoint_authenticationsession_factory_realm_extra_delay_f_done_f_session	_stopping)r\   main
transportsconfigrealmextraauthenticationr   is_fatalr'   rG   rX   
_transports                r#   r]   zComponent.__init__  sM   r 	
	
 (:DEE!HTNABB 1J j3*-C $I $J 
D)$J '
3NCI#%'$

 '
##!#z43N3NO 4  .3#2D r%   c                 J    | j                   D ]  }|j                         s y y)NTF)r   rh   )r\   rG   s     r#   _can_reconnectzComponent._can_reconnect  s&    ))I&&( * r%   c                    	
  j                   <t        j                         fd}t        j                   j                   ||       S t        j                          _          fd}t        j                   j                   ||       t	        j
                   j                        
dg fd 	fd 
fd	 j                  d       }t        j                  |	        j                   S )a  
        This starts the Component, which means it will start connecting
        (and re-connecting) to its configured transports. A Component
        runs until it is "done", which means one of:

        - There was a "main" function defined, and it completed successfully;
        - Something called ``.leave()`` on our session, and we left successfully;
        - ``.stop()`` was called, and completed successfully;
        - none of our transports were able to connect successfully (failure);

        :returns: a Future/Deferred which will resolve (to ``None``) when we are
            "done" or with an error if something went wrong.
        c                 2    t        j                  |        y N)txaioresolve)argds    r#   _cbzComponent._start.<locals>._cb;  s    a%r%   c                     d_         | S )z}
            if the _done_f future is resolved (good or bad), we want to set it
            to None in our class
            N)r   )r   r\   s    r#   _resetz Component._start.<locals>._resetE  s    
  DLJr%   r   c                 n   d _         j                  r!t        j                  j                  d        y j
                  j                  dt        j                  |              j
                  j                  dt        j                  |              t        j                  j                  |        y )NzInternal error {msg}msg{tb}tb)r   r   r   r   r   loginfofailure_messagedebugfailure_format_tracebackreject)failr\   s    r#   errorzComponent._start.<locals>.errorU  sw     DM~~
 dllD14%:O:OPT:UVv%*H*H*NOT\\40r%   c                     d _         	fdfdfd}fd}t        j                  j                  d         }t        j                  |||       y )Nc                    j                   j                  dt        j                  |              j                   j                  dt        j                  |              t        | j                  t              r6j                   j                  d| j                  j                                nt        | j                  t              r1j                   j                  dt        j                  |              nj                  | j                        r>| j                  j                  d   d   \  }}}j                   j                  d	|
       n0j                   j                  dt        j                  |              j                  d}nj                  | j                        }|r.j                   j                  d       d   j                          t        j                   dd        y )Nzcomponent failed: {error})r   r   r   z{msg}r   z&Connection failed with OS error: {msg}r   zTLS failure: {reason})reasonzConnection failed: {error}Fz"Error was fatal; failing transport)r   r   r   r   r   r   valuer
   r   error_messageOSErrorr   _is_ssl_errorargsr   re   
call_later)r   ssl_libssl_func
ssl_reasonr   r\   transport_candidatetransport_checks        r#   handle_connect_errorzGComponent._start.<locals>.attempt_connect.<locals>.handle_connect_errore  ss    :%BWBWX\B]^v%*H*H*NO djj*:;HHNN7

0H0H0JNK

G4 HHMM"JPUPePefjPkMl''

3 59JJOOA4Fq4I1GXzHHNN#::NNHHNN4#33D9 # 
 >>)$H#~~djj9HHHMM"FG'*113  OT:r%   c                      t        j                         j                  d j                        }t        j                  | fd fd       S )Nr   c                 0    t        j                        S r   r   r   _chain_fr   s    r#   <lambda>zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>      ell7D9r%   c                 0    t        j                        S r   r   r   s    r#   r   zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>  r   r%   )r   create_futurefirer   add_callbacks)r   	handler_fr   r\   s   ` @r#   notify_connect_errorzGComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error  sH    --/
 !II&6djjI	##99
 r%   c                 D     |       }t        j                  |d        y r   )r   r   )r   notify_fr   r   s     r#   connect_errorz@Component._start.<locals>.attempt_connect.<locals>.connect_error  s     /5##Hd4HIr%   c                 F    t        j                  j                  d        y r   )r   r   r   )xr\   s    r#   session_donez?Component._start.<locals>.attempt_connect.<locals>.session_done  s    dllD1r%   r   )r   r   	as_future_connect_oncer   )
r   r   r   	connect_fr   r   loopr\   r   r   s
       @@r#   attempt_connectz)Component._start.<locals>.attempt_connectb  sX     DM.`J2 "")!,I 	<Gr%   c                 \   j                   j                  d       j                         s)d}j                   j                  |       	 t	        |      	 t        	      }|j                         r|d<   n"|j                         }j                   j                  d|j                  |j                  |       t        j                  |      _        t        j                   j                         y # t        $ r*}t        j                  j                  |       Y d }~y d }~ww xY w)NzEntering re-connect loopz:Component failed: Exhausted all transport connect attemptsr   zZtrying transport {transport_idx} ("{transport_url}") using connect delay {transport_delay})transport_idxtransport_urltransport_delay)r   r   r   r   rD   r   r   r   nextrh   rl   warnrX   r'   sleepr   r   )
r   err_msgerG   delayr   r   r\   r   transport_gens
        r#   r   z)Component._start.<locals>.transport_check  s    HHNN56&&(Vg&&w//
  /	**,-6'*  ((*EHHMMl'mm'mm %	   "KK.DMF+ $ LLq1s   C8 8	D+ D&&D+r   )r   r   r   r   	itertoolscycler   r   )r\   r   r   r   start_fr   r   r   r   r   r   s   ``   @@@@@@r#   _startzComponent._start&  s    $ <<###%A& c37H **,	 	DLL&&9 "(8(89  !c	1L	H\	G 	G@ ))GT40G_e<||r%   c                    d| _         | j                  r4| j                  j                         r| j                  j                         S | j                  r.t        j                  t
        j                  | j                        S t        j                  | j                        s t        j                  | j                  d        t        j                  d       S )NT)r   r   is_attachedr   r   r   r   cancel	is_calledr   r   create_future_successrc   s    r#   stopzComponent.stop  s    ==T]]668==&&((]] ??5<<??
 t||,MM$,,-**400r%   c                 \     j                   j                  dj                  j                                t	        j
                          fd}xj                  dz  c_        t	        j                   j                  |      }fd}t	        j                  |d |       S )NzWconnecting once using transport type "{transport_type}" over endpoint "{endpoint_desc}")transport_typeendpoint_descc                  r   t        j                  j                        } 	 j                  |       x_        }j
                  j                         D ]D  \  }}t        |t              r|j                  |       (t        |fi |}|j                  |       F 	 |_        
fd}|j                  d|       
fd}j                  |j                  d|       
fd}|j                  d|       |S # t        $ r1}t        j                   |      }	t        j"                  
|	        d }~ww xY w)Nc                 H   j                   j                  d|       t        j                        so|j                  dv rt        j
                  d        y t        j                  t        |j                  |j                              }t        j                  |       y y )Nz"session leaving '{details.reason}'r}   )zwamp.close.normalzwamp.close.goodbye_and_out)
r   r   r   r   r   r   create_failurer
   messager   )r|   r}   fdoner\   s      r#   on_leavezAComponent._connect_once.<locals>.create_session.<locals>.on_leave  s~    HHMM< ' "  !??40">>-``!MM$5 % 4 4 0 Q!A "LLq1 1r%   r   c                     j                          xj                  dz  c_        j                  j                  d|       t	        j
                  j                         } fd} fd}t	        j                  |||       y )NrW   zsession on_join: {details}r  c                 r    j                   j                  d       fd}t        j                  d|       y )Nmain_successc                  F    	  j                          y # t        $ r Y y w xY wr   )r   r	   )r|   s   r#   r   zeComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success.<locals>.leave'  s%    % '#2 % !%%s    	  r   )r   r   r   r   )r   r   r\   r|   s     r#   r  zVComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success$  s*    ~6% ((E2r%   c                     j                   j                  d|        t        j                  |        j	                          y )Nzmain_error: {err})err)r   r   r   r   r   )r  r	  r\   r|   s    r#   
main_errorzTComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_error0  s2    ':DT3/**,r%   )r[   r`   r   r   r   r   r   r   )	r|   r}   r   r  r  r	  reactorr\   rG   s	   `    r#   on_joinz@Component._connect_once.<locals>.create_session.<locals>.on_join  sg    OO%..!3.HHNN#?NQWgFA
3- ''<Dr%   r@   c                     j                   j                  d|       t        j                        s5|sj                   j	                  d       y t        j
                  d        y y )Nz,session on_disconnect: was_clean={was_clean})	was_cleanzSession disconnected uncleanly)r   r   r   r   r   r   )r|   r  r	  r\   s     r#   on_disconnectzFComponent._connect_once.<locals>.create_session.<locals>.on_disconnect;  sW    HHNNF"+ #  !??40( HHMM @ "MM$5 1r%   r   )r   r   r   r   r   r   itemsr   r   add_authenticatorr   _parentr   r   	Exceptionr   r  r   )cfgr|   	auth_nameauth_configauthenticatorr
  r  r  r   r  r	  r  r\   rG   s             r#   create_sessionz/Component._connect_once.<locals>.create_session  s   !$++t{{;CZ*.*>*>s*CC.2.B.B.H.H.J*I{!+~>11+>(<Y(V+(V11-@ /K& #'
2 

7H-
E. ;;*JJvw/
6 

<7 c   ((+T1%s   A9C< <	D6,D11D6rW   c                     xj                   dz  c_         t        j                        st        j                  |        yy)a  
            this may seem redundant after looking at _connect_transport, but
            it will handle a case where something goes wrong in
            _connect_transport itself -- as the only connect our
            caller has is the 'done' future
            rW   N)ra   r   r   r   )r  r	  rG   s    r#   on_errorz)Component._connect_once.<locals>.on_errorU  s7     &&!+& ??4(T3' )r%   )
r   r   r   rn   r   r   r_   r   _connect_transportr   )r\   r  rG   r  r   r!  r	  s   ```   @r#   r   zComponent._connect_once  s    .$>>#557	 	 	
 ""$\	| 	""a'"OO##Y

	( 	AtX.r%   c                 (    | j                  d|       y)z
        A decorator as a shortcut for listening for 'join' events.

        For example::

           @component.on_join
           def joined(session, details):
               print("Session {} joined: {}".format(session, details))
        r@   Nr   r\   r~   s     r#   r  zComponent.on_joine  s     	r%   c                 (    | j                  d|       y)zM
        A decorator as a shortcut for listening for 'leave' events.
        r   Nr   r$  s     r#   r
  zComponent.on_leaveq       	r%   c                 (    | j                  d|       y)zO
        A decorator as a shortcut for listening for 'connect' events.
        r   Nr   r$  s     r#   
on_connectzComponent.on_connectw  s     		2r%   c                 (    | j                  d|       y)zR
        A decorator as a shortcut for listening for 'disconnect' events.
        r   Nr   r$  s     r#   r  zComponent.on_disconnect}  s     	b!r%   c                 (    | j                  d|       y)zM
        A decorator as a shortcut for listening for 'ready' events.
        r   Nr   r$  s     r#   on_readyzComponent.on_ready  r&  r%   c                 (    | j                  d|       y)zV
        A decorator as a shortcut for listening for 'connectfailure' events.
        r   Nr   r$  s     r#   on_connectfailurezComponent.on_connectfailure  s     	 "%r%   )NF)NNNrealm1NNNNr   )rp   rq   rr   rs   r   r{   r   r]   r   r   r   r   r  r
  r(  r  r+  r-  rt   r%   r#   r   r   g  sd    
 O.. W[EI}~l\1 B
"&r%   c                    
 t        |t              r|g}t        |      t        k7  r#t	        dj                  t        |                  |D ]5  }t        |t              rt	        dj                  t        |                   t        j                         fdfd

 fd}g }|D ]  } ||      }|j                  |        t        j                  |d      }r fd}	t        j                  ||	|	       |S )	a  
    Internal helper. Use "run" method from autobahn.twisted.wamp or
    autobahn.asyncio.wamp

    This is the generic parts of the run() method so that there's very
    little code in the twisted/asyncio specific run() methods.

    This is called by react() (or run_until_complete() so any errors
    coming out of this should be handled properly. Logging will
    already be started.
    zB"components" must be a list of Component objects - encountered {0}zN"components" must be a list of Component objects - encountereditem of type {0}c                 0    j                  d| |       |S )Nz-Component '{c}' successfully completed: {arg})cr   r   )compr   r   s     r#   component_successz_run.<locals>.component_success  s    		ATs	S
r%   c                     j                  d| t        j                  |             j                  dt        j                  |             y )NzComponent '{c}' error: {msg})r1  r   zComponent error: {tb}r   )r   r   r   r   r   )r3  r  r   s     r#   component_failurez_run.<locals>.component_failure  sC    		0De>S>STU>V	W		)e.L.LQ.O	P r%   c                     t        j                  | j                        }t        j                  |t	        |       t	        |              |S r   )r   r   r   r   r   )r3  r   r6  r4  r  s     r#   component_startz_run.<locals>.component_start  sG     OODJJ0%t,%t,	

 r%   F)consume_exceptionsc                 :    j                  d        |        y )Nz&All components ended; stopping reactorr2  )r   done_callbackr   r  s    r#   all_donez_run.<locals>.all_done  s    II>?'3'r%   )r   r   r   r<   r   r   r   make_loggerr   gatherr   )r  
componentsr;  r1  r8  dlr3  r   done_dr<  r6  r4  r   s   ` `       @@@r#   _runrB    s     *i( \
J46$z*+
 	

 !Y'##)6$q'?   


C	 
BD!
		!  \\"7F	( 	FHh7Mr%   r   )r   rj   	functoolsr   r   autobahn.utilr   autobahn.websocket.utilr   r;   autobahn.rawsocket.utilrC   autobahn.wamp.typesr   r   r   autobahn.wamp.exceptionr	   r
   autobahn.wamp.authr   r   autobahn.wamp.serializerr   __all__r$   rT   objectrE   r   rB  rt   r%   r#   <module>rM     sf   8     ) = = R R E C 1  
63r[|X# X#~f& f&RGr%   