
    :j7                     d    d Z ddlZddlZddlmZmZmZ ddlmZ	  ed      Z
 G d dee
         Zy)aF  
Generic Load Balancer

This module provides a generic load balancer for distributing requests
across multiple resources (sessions, tokens, user-agents, etc.).

Key Features:
- Round-robin and random load balancing strategies
- Thread-safe resource allocation
- Usage statistics tracking
- Simple and efficient implementation
    N)GenericListTypeVar)LoadBalanceStrategyTc                       e Zd ZdZej
                  fdee   defdZdefdZ	defdZ
dd	Zdee   ddfd
ZdefdZdefdZdefdZdefdZdefdZdefdZdefdZy)Balancerz/Generic load balancer for resource distributionitemsstrategyc                    |st        d      |j                         | _        || _        d| _        t        j                         | _        t        j                  t        t        | j                              d      | _        d| _        y)zInitialize load balancer

        Args:
            items: List of items to balance across
            strategy: Load balancing strategy to use
        Items list cannot be emptyr   N)
ValueErrorcopyr
   r   index	threadingLocklockdictfromkeysrangelenusage_counttotal_requests)selfr
   r   s      5/root/.openclaw/workspace/harvester/tools/balancer.py__init__zBalancer.__init__   sf     9::#jjl
 
NN$	  ==s4::)?C    returnc                    | j                   5  | xj                  dz  c_        | j                  t        j                  k(  r7| j
                  }| j
                  dz   t        | j                        z  | _        n,t        j                  dt        | j                        dz
        }| j                  |xx   dz  cc<   | j                  |   cddd       S # 1 sw Y   yxY w)zvGet next item according to load balancing strategy

        Returns:
            Any: Next item from the pool
           r   N)r   r   r   StrategyROUND_ROBINr   r   r
   randomrandintr   )r   
item_indexs     r   getzBalancer.get/   s     YY 
	*1$}} 4 44!ZZ
"jj1nDJJ?
#^^As4::/BC
Z(A-(::j)
	* 
	* 
	*s   B;CCc                 "    | j                         S )zjAlias for get() method for convenience

        Returns:
            Any: Next item from the pool
        )r&   r   s    r   nextzBalancer.nextA   s     xxzr   Nc                     | j                   5  d| _        t        j                  t	        t        | j                              d      | _        d| _        ddd       y# 1 sw Y   yxY w)z(Reset load balancer state and statisticsr   N)	r   r   r   r   r   r   r
   r   r   r(   s    r   resetzBalancer.resetI   sM    YY 	$DJ#}}U3tzz?-CQGD"#D	$ 	$ 	$s   AAA%c                    |st        d      | j                  5  |j                         | _        d| _        t
        j                  t        t        | j                              d      | _	        ddd       y# 1 sw Y   yxY w)z`Update items list

        Args:
            items: New list of items to balance across
        r   r   N)
r   r   r   r
   r   r   r   r   r   r   )r   r
   s     r   update_itemszBalancer.update_itemsP   sg     9::YY 	HDJDJ#}}U3tzz?-CQGD	H 	H 	Hs   AA77B c                    | j                   5  | j                  dk(  r7dt        | j                        | j                  j
                  i dcddd       S i }| j                  j                         D ],  \  }}|| j                  z  dz  }|t        |d      d|d| <   . | j                  t        | j                        | j                  j
                  |dcddd       S # 1 sw Y   yxY w)zsGet usage statistics

        Returns:
            dict: Usage statistics including counts and percentages
        r   )r   items_countr   usage_distributionNd      )count
percentageitem_)r   r   r   r
   r   valuer   round)r   distributionir3   r4   s        r   	get_statszBalancer.get_stats^   s     YY 	""a'&'#&tzz? $ 3 3*,		 	 L ,,224 a5#d&9&99S@
6;5Q[]^K_,`uQC[)a
 #'"5"5"4:: MM//&2		 	 	s   =C BC  C)c                    | j                   5  | j                  t        j                  k(  r"| j                  | j
                     cddd       S t        j                  | j                        cddd       S # 1 sw Y   yxY w)zGet current item without advancing the index

        Returns:
            T: Current item (for round-robin) or random item
        N)r   r   r!   r"   r
   r   r#   choicer(   s    r   get_current_itemzBalancer.get_current_itemy   s^     YY 	1}} 4 44zz$**-	1 	1 }}TZZ0		1 	1 	1s   6A5A55A>c                 ,    t        | j                        S z[Get number of items in the pool

        Returns:
            int: Number of items
        r   r
   r(   s    r   sizezBalancer.size        4::r   c                 2    t        | j                        dk(  S )z_Check if items pool is empty

        Returns:
            bool: True if pool is empty
        r   r@   r(   s    r   is_emptyzBalancer.is_empty   s     4::!##r   c                 ,    t        | j                        S r?   r@   r(   s    r   __len__zBalancer.__len__   rB   r   c                 |    dt        | j                         d| j                  j                   d| j                   dS )zgString representation of the balancer

        Returns:
            str: String representation
        Balancer(items=, strategy=z, requests=))r   r
   r   r6   r   r(   s    r   __str__zBalancer.__str__   s=     !TZZ 1T]]=P=P<QQ\]a]p]p\qqrssr   c                 V    d| j                    d| j                   d| j                   dS )zbDetailed string representation

        Returns:
            str: Detailed representation
        rH   rI   z, index=rJ   )r
   r   r   r(   s    r   __repr__zBalancer.__repr__   s,     !KhtzzlZ[\\r   )r   N)__name__
__module____qualname____doc__r!   r"   r   r   r   r&   r)   r+   r-   r   r:   r=   intrA   boolrD   rF   strrK   rM    r   r   r	   r	      s    9<D<P<P  d1g    &*Q *$a $H$q' Hd H4 6
1! 
1c $$ $ t t]# ]r   r	   )rQ   r#   r   typingr   r   r   
core.enumsr   r!   r   r	   rU   r   r   <module>rX      s8      ) ) 6CLR]wqz R]r   