U
    ^»{jn"  ã                   @  sÒ   d Z ddlm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
 ddlZddlmZ ddlmZmZmZ e
r”dd	l	mZmZmZ dd
lmZ eejdd… dkp²e ¡ dkƒZe e¡ZG dd„ dƒZdS )z8Provides a channel based on operating system file pipes.é    )ÚannotationsN)ÚLock)ÚTYPE_CHECKINGé   )Ú_wire)ÚBlockWarningÚChannelClosedErrorÚ	JSONError)ÚAnyÚMappingÚSequence)ÚBrowserResponseé   )r   é   ÚWindowsc                   @  s¶   e Zd ZU dZded< ded< ded< ddœd	d
„Zddœdd„Zddœdd„Zdddœdd„Zddœdddœdd„Z	dddœdd„Z
dddœdd„Zddœdd „Zddœd!d"„Zd#S )$ÚPipez!Defines an operating system pipe.ÚintÚfrom_external_to_choreoÚfrom_choreo_to_externalr   Úshutdown_lockÚNone)Úreturnc                 C  sL   t t ¡ ƒ\| _| _t t ¡ ƒ\| _| _| j| _| j| _t	ƒ | _
t	ƒ | _dS )z$Construct a pipe using os functions.N)ÚlistÚosÚpipeÚ_read_from_browserÚ_write_from_browserÚ_read_to_browserÚ_write_to_browserr   r   r   r   Ú
_open_lock©Úself© r"   úZ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/choreographer/channels/pipe.pyÚ__init__(   s    zPipe.__init__Úboolc                 C  s   | j  ¡  o| j ¡ S )zReturn true if pipe open.)r   Úlockedr   r    r"   r"   r#   Úis_ready@   s    zPipe.is_readyc                 C  s   | j jdd�stdƒ‚dS )a.  
        Open the channel.

        In a sense, __init__ creates the pipe. The OS opens it.
        Here we're just marking it open for use, that said.

        We only use locks here for indications, we never actually lock,
        because the broker is in charge of all async/parallel stuff.
        F©ÚblockingzCannot open same pipe twice.N)r   ÚacquireÚRuntimeErrorr    r"   r"   r#   ÚopenD   s    
z	Pipe.openzMapping[str, Any])Úobjr   c              
   C  sì   |   ¡ stdƒ‚t |¡d }t d|dd… ›d|dd… ›dt|ƒ› d	�¡ t d
|›�¡ zVt 	| j
|¡}t d|› dt|ƒ› d�¡ |t|ƒkr´t d|› dt|ƒ› d�¡ W n0 tk
ræ } z|  ¡  t|‚W 5 d}~X Y nX dS )zz
        Send one json down the pipe.

        Args:
            obj: any python object that serializes to json.

        ú\The communication channel was either never opened or closed. Was .open() or .close() called?ó    zWriting message Né   ú...éñÿÿÿz, size: Ú.zFull Message: z	***Wrote ú/z***z!***Did not write entire message. )r'   r   ÚwireÚ	serializeÚ_loggerÚdebugÚlenÚdebug2r   Úwriter   ÚcriticalÚOSErrorÚclose)r!   r-   Zencoded_messageÚretÚer"   r"   r#   Ú
write_jsonQ   s*    ÿ*ÿÿÿzPipe.write_jsonTr(   zSequence[BrowserResponse])r)   r   c          	      C  s�  g }|   ¡ stdƒ‚ts(|s(t dt¡ ztr<t | j|¡ W n0 t	k
rn } z|  
¡  t|‚W 5 d}~X Y nX d}d}�zBzÊt | jd
¡}t d|dd… ›d|dd… ›dt|ƒ› d�¡ t d	|›�¡ |rÚ|dkrü|rðt d|›d�¡ |  
¡  t‚|d dk�rDt d¡ |d7 }t�r0t | jd¡ |t | jd
¡7 }qüW nr tk
�rn   t d¡ | Y W ¢RS  t	k
�r¸ } z,t d¡ |  
¡  |�r¢|dk�r¨t|‚W 5 d}~X Y nX W 5 t d|› d|�rØt|ƒnd› d�¡ t d	|›�¡ X |dk�r|S | d¡}| d¡}t dt|ƒ› d�¡ |D ]X}|�r2z| t |¡¡ W n6 tk
�rp   t d¡ Y n   t d¡ ‚ Y nX �q2|S )zÍ
        Read from the pipe and return one or more jsons in a list.

        Args:
            blocking: The read option can be set to block or not.

        Returns:
            A list of jsons.

        r.   z;Windows python version < 3.12 does not support non-blockingNr   zTotal loops: z, Final size: r   r3   zWhole buffer: i'  zFirst read in loop: r0   r1   r2   z. size: ó   {bye}
z	Received z	. is bye?éÿÿÿÿz&Partial message from browser received.TÚBlockingIOErrorr=   zutf-8ú z raw_messages.z$JSONError decoding message. Ignoringz,Error in trying to decode JSON off our read.)r'   r   Ú_with_blockÚwarningsÚwarnr   r   Úset_blockingr   r=   r>   r7   r8   r9   r:   ÚreadrD   ÚdecodeÚsplitÚappendr5   Zdeserializer	   Ú	exception)	r!   r)   Zjsonsr@   Z
raw_bufferZ
loop_countZdecoded_bufferZraw_messagesZraw_messager"   r"   r#   Ú
read_jsonsq   s‚    ÿþþ*ÿ


ÿ



zPipe.read_jsons)Úfdr   c                 C  s.   zt rt |d¡ W n tk
r(   Y nX d S )NF)rF   r   rI   Ú	Exception©r!   rP   r"   r"   r#   Ú_unblock_fdÈ   s
    zPipe._unblock_fdc                 C  s(   zt  |¡ W n tk
r"   Y nX d S )N)r   r>   rQ   rR   r"   r"   r#   Ú	_close_fdÏ   s    zPipe._close_fdc                 C  s8   |   | j¡ zt | jd¡ W n tk
r2   Y nX d S )NrB   )rS   r   r   r;   rQ   r    r"   r"   r#   Ú	_fake_byeÕ   s
    zPipe._fake_byec                 C  s†   | j jdd�r‚t ¡ dkr"|  ¡  |  | j¡ |  | j¡ |  | j¡ |  | j	¡ |  
| j¡ |  
| j¡ |  
| j¡ |  
| j	¡ dS )zClose the pipe.Fr(   r   N)r   r*   ÚplatformÚsystemrU   rS   r   r   r   r   rT   r    r"   r"   r#   r>   Ü   s    z
Pipe.closeN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r$   r'   r,   rA   rO   rS   rT   rU   r>   r"   r"   r"   r#   r      s   
#ýWr   ) r[   Ú
__future__r   r   rV   ÚsysrG   Ú	threadingr   Útypingr   ZlogistroÚ r   r5   Ú_errorsr   r   r	   r
   r   r   Zchoreographer.protocolr   r%   Úversion_inforW   rF   Ú	getLoggerrX   r7   r   r"   r"   r"   r#   Ú<module>   s    "
