
    :jc                        d 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	m
Z
  ed      Z	 ddlZdZ	 ddlZdZej"                  d	        Zdd
edefdZ G d d      ZdeddfdZy# e$ r dZdZY @w xY w# e$ r dZdZY Hw xY w)z.
Atomic file operations and repair utilities.
    N)List)
get_logger)handle_exceptionsstorageTFc              #   j  K   d}	 t         r6	 t        j                  | j                         t        j                         d}n<t        r6	 t        j                  | j                         t        j                  d       d}d |rv	 t         r3t        j                  | j                         t        j                         n;t        r4t        j                  | j                         t        j                  d       yyyy# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r Y yw xY w# |r	 t         r3t        j                  | j                         t        j                         w t        r4t        j                  | j                         t        j                  d       w w # t
        $ r Y w w xY ww xY ww)zmBest-effort exclusive file lock around writes.

    Falls back to no-op if platform lock is unavailable.
    FT   N)
_HAS_FCNTLfcntlflockfilenoLOCK_EX	Exception_HAS_MSVCRTmsvcrtlockingLK_NBLCKLOCK_UNLK_UNLCK)fobjlockeds     5/root/.openclaw/workspace/harvester/storage/atomic.py_exclusive_file_lockr   "   sN     FDKKM5==9 t{{}fooqA 	 KKu}}= NN4;;=&//1E ! >        KKu}}= NN4;;=&//1E !  s   F3D( 4C; D( 	5D
 >D( F3A2D 7F3;	DD( DD( 
	DD( DD( 	D%"F3$D%%F3(F0,8F $F0%9F F0 	F,)F0+F,,F00F3max_retries
base_delayc                       fd}|S )zHRetry decorator for Windows file locking issues with exponential backoffc                       fd}|S )Nc                  J   d }t        dz         D ]  }	  | i |c S  |# t        t        f$ rp}|}t        |d      r\|j                  dk(  rM|k  rHd|z  z  }t
        j                  d|dd|dz    ddz    d	       t        j                  |       Y d }~ d }~ww xY w)
Nr   winerror       z(Windows file lock detected, retrying in z.2fzs (attempt /))	rangePermissionErrorOSErrorhasattrr   loggerdebugtimesleep)	argskwargslast_exceptionattemptedelayr   funcr   s	         r   wrapperz:_retry_on_windows_lock.<locals>.decorator.<locals>.wrapperI   s    !N q1 000" !  (1 %&Nq*-!**2B"[0$.!W*$=E"LL"J5QT+U`ahklal`mmnoz}~o~n  @A  !B !JJu-$s   #B"A%BBB" )r1   r2   r   r   s   ` r   	decoratorz)_retry_on_windows_lock.<locals>.decoratorH   s    	!*     r3   )r   r   r4   s   `` r   _retry_on_windows_lockr6   E   s    0 r5   c            	           e Zd ZdZe edd       eddd      d	ed
eddfd                     Ze edd      d	ede	e   ddfd              Z
y)AtomicFileWriterz:Atomic file operations to prevent corruption during writes   皙?)r   r   NerrorT)default_result	log_levelreraisefilepathcontentreturnc                    t         j                  j                  |       }t        j                  |d       d}	 t	        j
                  dd|dd      5 }|j                  |       |j                          t        j                  |j                                |j                  }ddd       t        rat         j                  j                  |       rB	 t        | d	      5 }t        |      5  t        j                  ||        ddd       ddd       yyt        j                  ||        y# 1 sw Y   xY w# 1 sw Y   6xY w# 1 sw Y   9xY w# t         t"        f$ r t        j                  ||        Y yw xY w# t$        $ rI |rEt         j                  j                  |      r&	 t        j&                  |        # t"        $ r Y  w xY w w xY w)
zQWrite content to file atomically using temp file + rename with Windows-safe retryTexist_okNwutf-8Fz.tmp)modeencodingdirdeletesuffixzr+b)ospathdirnamemakedirstempfileNamedTemporaryFilewriteflushfsyncr   namer   existsopenr   replacer$   r%   r   unlink)r?   r@   	directory	temp_path	temp_filetarget_files         r   write_atomiczAtomicFileWriter.write_atomicf   s   
 GGOOH-	
I-		,,7	%PV +(!))+,%NN	+ rww~~h74h. 8+?ST_?` 8

9h78 8 8 

9h/%+ +8 8 8 8'1 4JJy(34  	RWW^^I6IIi(   	s   E: AD+%-E: E E+D7E
E E: +D40E: 7E 	<EEE %E74E: 6E77E: :*G%F;:G;	GGGG)r<   r=   linesc                    t         j                  j                  |       }t        j                  |d       t	        | dd      5 }t        |      5  |D ]6  }|j                  |       |j                  d      r&|j                  d       8 |j                          t        j                  |j                                ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)zBAppend lines to file atomically with fsync and resource managementTrC   arF   )rH   
N)rL   rM   rN   rO   rW   r   rR   endswithrS   rT   r   )r?   r_   rZ   flines        r   append_atomiczAtomicFileWriter.append_atomic   s     GGOOH-	
I- (C'2 	!a9Ma9P 	! "}}T*GGDM" GGIHHQXXZ 	! 	! 	! 	! 	! 	!s+   C(C:AC CC	CC&)__name__
__module____qualname____doc__staticmethodr6   r   strr^   r   rf   r3   r5   r   r8   r8   c   s    Dc:dgtL#s #S #T # M ; #J dg>! !DI !$ ! ? !r5   r8   
shard_pathrA   c                    	 t        | d      5 }|j                  dt        j                         |j	                         }|dk(  r
	 ddd       yd}t        d||z
        }|j                  |       |j                         }ddd       j                  d      sj|j                  d      }|dk(  r't        | d      5 }|j                         ddd       yt        | d      5 }|j                  |z   dz          ddd       yy# 1 sw Y   xY w# 1 sw Y   yxY w# 1 sw Y   yxY w# t        $ r%}t        j                  d	|  d
|        Y d}~yd}~ww xY w)zBest-effort trim the last line if it is a partial JSON object.

    This function reads last bytes and ensures the file ends with a newline.
    Utility function for both snapshot building and recovery operations.
    rbr   Ni      
zrb+r   z&[storage] failed to repair shard tail z: )rW   seekrL   SEEK_ENDtellmaxreadrc   rfindtruncater   r'   r;   )	rm   rd   sizebackstarttailnlrE   r/   s	            r   repair_trailing_partialr~      sE   Q*d# 		qFF1bkk"668Dqy			 		 D4$;'EFF5M668D		 }}U#E"BRx*e, &JJu%&j%( +A

52:>*+ + $		 		 &+ + Q=j\A3OPPQs|   D( 7DD( 2D ;D( ;DD( D( "D:D( D	D( DD( D( D%!D( %D( (	E1EE)r9   r:   )rj   
contextlibrL   rP   r)   typingr   tools.loggerr   tools.utilsr   r'   r
   r	   r   r   r   contextmanagerr   intfloatr6   r8   rl   r~   r3   r5   r   <module>r      s     	    # )	I	J
K  D U <9! 9!xQ Q QU  EJ  FKs"   A) A8 )	A54A58	BB