
    ^jn                        d Z ddlZddlZddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZmZ  ej"                  e      ZdZd	Ze G d
 d             Ze G d d             Zde	fdZdede	fdZdededz  fdZdddedededededz  dedz  dedz  dee   dee   dz  ddfdZdeddfdZde	deddfd Z y)!z?Best-effort local cache for SandboxPool hosts (host/pool mode).    N)asdict	dataclassfield)Path)List   )	constants)WeakFileLockloggingg      @c                   \    e Zd ZU dZeed<   eed<   eed<   eed<   eed<   eed<   dZeed	<   y
)
CachedHostaC  A single host Job of a pool, as last seen by some process.

    `base_url` + `nonce` are everything needed to rebuild the in-job server transport
    (`_SandboxServer`) without an `inspect_job` round-trip: the per-sandbox auth token is
    re-derived from the user's HF token and `nonce` (see `_derive_sandbox_token`).
    job_idownerbase_urlnoncecapacitylive        
updated_atN)	__name__
__module____qualname____doc__str__annotations__intr   float     i/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/huggingface_hub/_sandbox_cache.pyr   r   &   s1     KJMJM
IJr   r   c                       e Zd ZU dZeed<   eed<   eed<   eed<   edz  ed<   edz  ed<   edz  ed	<    ee
      Z	e
e   ed<   eZeed<   dZeed<   y)	PoolCachezJCached view of one pool: its config (to boot new hosts) + its known hosts.pool_idimageflavorsandboxes_per_hostN	max_hostsidle_timeout	namespace)default_factoryhostsversionr   r   )r   r   r   r   r   r   r   r   listr+   r   r   _CACHE_VERSIONr,   r   r   r   r   r    r"   r"   8   s`    TLJKTz*Tz#D9E4
9!GS!Jr   r"   returnc                  @    t        t        j                        dz  dz  S )Nsandboxpools)r   r	   HF_HOMEr   r   r    
_pools_dirr4   H   s    	!!"Y.88r   r#   c                 p     t         fddD              s dv rt        d       t                 dz  S )z.Path of the cache file for `pool_id` (no I/O).c              3   &   K   | ]  }|v  
 y w)Nr   ).0cr#   s     r    	<genexpr>z"pool_cache_path.<locals>.<genexpr>N   s     
5A1<
5s   )/\ ).z..zInvalid pool id: z.json)any
ValueErrorr4   )r#   s   `r    pool_cache_pathr@   L   s@    

5!4
55K9O,WK899<WIU+++r   c                    	 t        |       }|j                  dd      5 }t        j                  |      }ddd       j	                  d      t
        k7  ry|j                  dg       D cg c]  }t        d	i | }}t        d	i |d|iS # 1 sw Y   YxY wc c}w # t        $ r Y yt        $ r%}t        j                  d| d|        Y d}~yd}~ww xY w)
zOReturn the cached view of `pool_id`, or `None` if missing/corrupt/incompatible.rutf-8encodingNr,   r+   z+Ignoring unreadable sandbox pool cache for : r   )r@   openjsonloadgetr.   popr   r"   FileNotFoundError	Exceptionloggerdebug)r#   pathfdatahr+   es          r    read_pool_cacherU   S   s    w'YYsWY- 	 99Q<D	 88I.0*.((7B*?@Qa@@-4-u--	  	  A  B7+RPQsSTsE   B B B B +B=B BB 	C*C2CC)dead_host_idsr$   r%   r&   r'   r(   r)   r+   rV   c                   |xs
 t               }		 t        |       }
|
j                  j                  dd       t	        t        |
      dz   t              5  t        |       }|r|j                  ng D ci c]  }|j                  | }}|D ]  }|||j                  <    |	D ]  }|j                  |d        t        | ||||||t        |j                               t        j                         	      }t        |
|       ddd       yc c}w # 1 sw Y   yxY w# t         $ r%}t"        j%                  d| d|        Y d}~yd}~ww xY w)	a  Merge `hosts` into the cache for `pool_id` (best-effort, never raises).

    Concurrency-safe: under a file lock, the on-disk hosts are read, then `hosts` are
    upserted by `job_id` and `dead_host_ids` removed, so a process only adds/updates what
    it learned and never drops hosts another process discovered. The result is written
    atomically. The pool config is refreshed from the arguments.
    T)parentsexist_okz.lock)timeoutN)	r#   r$   r%   r&   r'   r(   r)   r+   r   z'Could not write sandbox pool cache for rF   )setr@   parentmkdirr
   r   _LOCK_TIMEOUTrU   r+   r   rK   r"   r-   valuestime_atomic_writerM   rN   rO   )r#   r$   r%   r&   r'   r(   r)   r+   rV   deadrP   existingrS   mergedhostr   cacherT   s                     r    save_pool_cacherg   d   s@   & !CEDQw'$6#d)g-}E 	'&w/H>FHNNBPaahhkPFP +&*t{{#+ )

64()#5#)#6==?+99;
E $&%	' 	'P	' 	'&  Q>wkA3OPPQsI   AD D3D
A:DD 
DDD D 	E	$EE	c                     	 t        |       j                  d       y# t        $ r%}t        j	                  d|  d|        Y d}~yd}~ww xY w)z@Remove the cache file for `pool_id` (best-effort, never raises).T)
missing_okz(Could not delete sandbox pool cache for rF   N)r@   unlinkrM   rN   rO   )r#   rT   s     r    delete_pool_cacherk      sM    P ''4'8 P?y1#NOOPs    	AAArP   rf   c                 $   | j                   | j                   dt        j                          dz  }|j	                  dd      5 }t        j                  t        |      |d       ddd       t        j                  ||        y# 1 sw Y    xY w)	zSWrite the cache via a temp file + `os.replace` so readers never see a partial file.r=   z.tmpwrC   rD      )indentN)	r\   nameosgetpidrG   rH   dumpr   replace)rP   rf   tmprQ   s       r    ra   ra      sp    
++499+Qryy{m48
8C	#	( .A		&-1-.JJsD. .s   "BB)!r   rH   rq   r`   dataclassesr   r   r   pathlibr   typingr    r	   utilsr
   r   
get_loggerr   rN   r.   r^   r   r"   r4   r   r@   rU   r   r[   rg   rk   ra   r   r   r    <module>r|      sr   F  	  0 0    ( 
		H	%     "   9D 9,S ,T ,S Y%5 6 &*+Q+Q +Q 	+Q
 +Q Tz+Q *+Q Tz+Q 
+Q s8d?+Q 
+Q\Ps Pt P Y 4 r   