o
    iV                     @  st   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ e	dddG d	d
 d
ZG dd dZdS )zIn-memory rate limiter with tenant, app, and IP dimensions.

The public interface is intentionally simple so it can be swapped for Redis or
another distributed backend later without changing the gateway contract.
    )annotationsN)defaultdictdeque)	dataclass)DequeT)frozenslotsc                   @  s:   e Zd ZU dZded< ded< ded< ded< ded	< d
S )RateLimitResultzOutcome of a rate-limit check.boolallowedstrkeyint	remaininglimitwindow_secondsN)__name__
__module____qualname____doc____annotations__ r   r   platform/quotas/rate_limiter.pyr	      s   
 r	   c                   @  s@   e Zd ZdZddddd
dZdddZdddddddZdS )RateLimiterzAWindowed in-memory limiter prepared for future Redis replacement.x   <   )default_limitr   r   r   r   returnNonec                C  s$   || _ || _tt| _t | _d S )N)r   r   r   r   _events	threadingLock_lock)selfr   r   r   r   r   __init__   s   
zRateLimiter.__init__	tenant_id
str | Noneapp_id
ip_addressr   c                C  s4   |r|rd| d| S |rd| S d|pd S )Nztenant:z:app:zip:unknownr   )r#   r%   r'   r(   r   r   r   	build_key$   s
   
zRateLimiter.build_keyN)requesttenantr'   r	   c          
      C  s
  |r	|pi  dnd }|d urt|dd nd }| j|||d}t }| jU | j| }|rF||d  | jkrF|  |rF||d  | jks7t|| j	kr^t
d|d| j	| jW  d    S || | j	t| }	t
d||	| j	| jW  d    S 1 s~w   Y  d S )Nr%   remote_addr)r%   r'   r(   r   FT)getgetattrr*   timer"   r   r   popleftlenr   r	   append)
r#   r+   r,   r'   r%   r(   r   noweventsr   r   r   r   check+   s    

$zRateLimiter.check)r   r   r   r   r   r   )r%   r&   r'   r&   r(   r&   r   r   )r'   r&   r   r	   )r   r   r   r   r$   r*   r6   r   r   r   r   r      s
    
r   )r   
__future__r   r    r0   collectionsr   r   dataclassesr   typingr   r	   r   r   r   r   r   <module>   s    

