
    :j                        d 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 ddl	m
Z
 ddlmZmZ ddlmZ  ed	      Ze G d
 d             Ze G d d             Z G d d      Z G d d      Zdeeef   defdZedk(  re
 eddd      d eddd      iZ ee      Zej3                  d        ed      D ]1  Zej9                  e
      Zej3                  dedz    d erd!nd"        3  ej<                  d       ej9                  e
      Zej3                  d#erd!nd"        ej3                  d$        ed      D ]  Zej?                  e
d%        ejA                         Z!ej3                  d&e!        ej3                  d'       yy)(z
Rate limiting system using Token Bucket algorithm.
Supports per-service rate limits with adaptive adjustment and burst handling.
    N)	dataclass)DictOptional)SERVICE_TYPE_GITHUB_API)RateLimitConfigTokenBucket   )
get_loggertoolsc                   b    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<   eed<   eed	<   y
)TokenBucketStatsz$Statistics for a single token bucketratebursttokensutilizationconsecutive_successconsecutive_failuresadaptiveoriginal_rateN)__name__
__module____qualname____doc__float__annotations__     6/root/.openclaw/workspace/harvester/tools/ratelimit.pyr   r      s1    .
KLMOr   r   c                   &    e Zd ZU dZeeef   ed<   y)RateLimiterStatszOverall rate limiter statisticsservicesN)r   r   r   r   r   strr   r   r   r   r   r    r    $   s    )3(())r   r    c                       e Zd ZdZdeeef   fdZddedede	fdZ
ddededefdZded	e	fd
ZdedefdZdedefdZdefdZdedee   fdZy)RateLimiterz6Multi-service rate limiter with Token Bucket algorithmrate_limitsc                 >   i | _         t        j                         | _        |j	                         D ]>  \  }}t        |j                  |j                  |j                        | j                   |<   @ t        j                  dt        | j                          d       y )Nr   r   r   zInitialized rate limiter with z	 services)buckets	threadingLocklockitemsr   	base_rateburst_limitr   loggerinfolen)selfr%   servicelimits       r   __init__zRateLimiter.__init__.   s    /1NN$	 *//1 	xNGU$/U__EL]L]hmhvhv$wDLL!	x 	4S5F4GyQRr   r3   r   returnc                 L    | j                  |      }|sy|j                  |      S )zAcquire tokens for a serviceT)_get_bucketacquirer2   r3   r   buckets       r   r9   zRateLimiter.acquire8   s'    !!'*~~f%%r   c                 L    | j                  |      }|sy|j                  |      S )zGet wait time needed for tokensg        )r8   	wait_timer:   s       r   r=   zRateLimiter.wait_time@   s)    !!'*''r   successc                 N    | j                  |      }|r|j                  |       yy)z2Report request result for adaptive rate adjustmentN)r8   adjust_rate)r2   r3   r>   r;   s       r   report_resultzRateLimiter.report_resultH   s(    !!'*w' r   
rate_limitc                     | j                   5  t        |j                  |j                  |j                        | j
                  |<   t        j                  d|        ddd       y# 1 sw Y   yxY w)zAdd a new service rate limitr'   zAdded rate limit for service: N)r+   r   r-   r.   r   r(   r/   r0   )r2   r3   rB   s      r   add_servicezRateLimiter.add_serviceN   se    YY 	D$/))1G1GR\ReRe%DLL! KK8	BC		D 	D 	Ds   AA((A1c                 8   | j                   5  || j                  v rk| j                  |   }|j                  |_        |j                  |_        |j                  |_        |j                  |_        t        j                  d|        ddd       y# 1 sw Y   yxY w)z"Update existing service rate limitz Updated rate limit for service: N)
r+   r(   r-   r   r.   r   r   r   r/   r0   )r2   r3   rB   r;   s       r   update_servicezRateLimiter.update_serviceV   s    YY 	J$,,&g.(22)55","5"5'1';';$>wiHI	J 	J 	Js   A:BBc                 "   i }| j                   5  | j                  j                         D ]C  \  }}|j                         }t	        |d   |d   |d   |d   |d   |d   |d   |d   	      ||<   E 	 d
d
d
       t        |      S # 1 sw Y   xY w)zGet statistics for all servicesr   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   N)r!   )r+   r(   r,   	get_statsr   r    )r2   r!   r3   r;   bucket_statss        r   rH   zRateLimiter.get_statsa   s    YY 	#'<<#5#5#7 %//1$4%f-&w/'1 ,] ;(45J(K)56L)M)*5"."?	%!	  22	 	s   A!BBc                 |    | j                   5  | j                  j                  |      cddd       S # 1 sw Y   yxY w)z#Get bucket for service, thread-safeN)r+   r(   get)r2   r3   s     r   r8   zRateLimiter._get_buckets   s0    YY 	-<<##G,	- 	- 	-s   2;Nr	   )r   r   r   r   r   r"   r   r5   intboolr9   r   r=   rA   rD   rF   r    rH   r   r   r8   r   r   r   r$   r$   +   s    @SDo)=$> S&s &C & &( (c (% ((S (4 (D3 DO D	Jc 	J 	J3+ 3$-3 -8K+@ -r   r$   c                   B    e Zd ZdZdefdZddededefdZ	dedefd	Z
y
)AsyncRateLimiterz5Async wrapper for rate limiter with automatic waitingrate_limiterc                     || _         y )N)rQ   )r2   rQ   s     r   r5   zAsyncRateLimiter.__init__|   s
    (r   r3   r   r6   c                   K   | j                   j                  ||      ry| j                   j                  ||      }|dkD  r| j                   j                  |      }|r|j                  nd}t
        j                  d| d|dd|        t        j                  |       d{    | j                   j                  ||      S y	7 !w)
z$Acquire tokens, waiting if necessaryTr   unknownzRate limit hit for z
, waiting z.2fzs, max: NF)	rQ   r9   r=   r8   r   r/   debugasynciosleep)r2   r3   r   r=   r;   	max_values         r   r9   zAsyncRateLimiter.acquire   s      $$Wf5 %%//@	q=&&227;F(.IILL.wiz)CPXYbXcde--	***$$,,Wf== +s   B!C#C$"Cr>   c                 <    | j                   j                  ||       y)zReport request resultN)rQ   rA   )r2   r3   r>   s      r   rA   zAsyncRateLimiter.report_result   s    ''9r   NrL   )r   r   r   r   r$   r5   r"   rM   rN   r9   rA   r   r   r   rP   rP   y   s>    ?)[ )S # d $:S :4 :r   rP   r%   r6   c                     t        |       S )z'Factory function to create rate limiter)r$   )r%   s    r   create_rate_limiterr[      s    {##r   __main__g       @   T)r-   r.   r   openaig      ?   zTesting rate limiter...   zRequest z: u   ✓u   ✗zAfter 1s wait: zTesting adaptive adjustment...FzStats after failures: zRate limiter test completed!)"r   rV   r)   timedataclassesr   typingr   r   constant.systemr   core.modelsr   r   r/   r
   r   r    r$   rP   r"   r[   r   limitslimiterr0   rangeir9   r>   rW   rA   rH   statsr   r   r   <module>rk      s  
    ! ! 3 4 	G	 
 
 
 * * *K- K-\: ::$T#*>%? $K $
 z 	 3AX\!]/CQNF
 "&)G KK)* 1X E//"9:hqse2weE%BCDE
 DJJqMoo56G
KK/7%!>?@ KK011X >5u=> E
KK(01
KK./? r   