U
    ɳ`iX8                     @   sh   d Z ddlZddlmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ G dd	 d	Zed
dZdS )z~
FIXED Call Manager for Handling Multiple Concurrent Calls
Manages call sessions with proper concurrency limits and isolation
    N)DictOptional)	WebSocket)Log)CallSession)Configc                   @   s   e Zd ZdZdedddZeeee	 dddZ
ed	d
ddZeee	 d
ddZedddZedddZeeef dddZd	dddZed	d
ddZd	S )CallManagerz
    Manages multiple concurrent call sessions with proper isolation.
    Each call gets its own completely isolated session.
    2   max_concurrent_callsc                 C   s6   || _ i | _t|| _t | _td|  d S )Nz1Call Manager initialized - Max concurrent calls: )	r   active_sessionsasyncio	SemaphoreZcall_semaphoreLocksession_lockr   info)selfr    r   :/var/www/html/live_calls/homebook/services/call_manager.py__init__   s
    
zCallManager.__init__)
session_id	websocketreturnc              
      s  zt | j| jkrDtd| j d|  |jdddI dH  W dS t||}| I dH srtd|  W dS | j	4 I dH  || j|< W 5 Q I dH R X t
d| d	t | j d
| j d |W S  tk
r@ } zZt|}d|ksd|krtd| d W Y (dS td| d|  W Y dS W 5 d}~X Y n@ tk
r~ } z td| d|  W Y dS d}~X Y nX dS )z
        Create a new isolated call session with proper error handling.
        Returns None if max concurrent calls reached or if creation fails.
        u"   ❌ Max concurrent calls reached (z). Rejecting session i  z.Service overloaded - too many concurrent calls)codereasonNu!   ❌ Failed to initialize session u   ✅ Created call session 
 (Active: /)different loopattached to a different loopu7   ⚠️ Event loop mismatch during session creation for z - retrying...u(   ❌ Runtime error creating call session : u    ❌ Error creating call session )lenr   r   r   warningcloser   
initializeerrorr   r   RuntimeErrorstr	Exception)r   r   r   sessione	error_msgr   r   r   create_call_session   s.    
&
zCallManager.create_call_sessionN)r   r   c              
      s  d}ztt d|  | j4 I dH V || jkrP| j|}t d|  n(t d| d W 5 Q I dH R  W dS W 5 Q I dH R X |rxz"| I dH  t d|  W n tk
r } zHt|}d|ksd|krt 	d	| d
 nt 
d| d|   W 5 d}~X Y n: tk
rP } zt 
d| d|  W 5 d}~X Y nX t d| dt| j d| j d W nz tk
r } zZt|}d|ksd|krt 	d| d n&t 
d| d|  ddl}|  W 5 d}~X Y nX dS )zBRemove and cleanup a call session with proper event loop handling.Nu'   🔄 Attempting to remove call session u!   🧹 Calling cleanup for session zSession z( already removed (likely race condition)u#   ✅ Cleanup successful for session r   r   .   ⚠️ Event loop mismatch during cleanup for z& - resources will be garbage collectedu-   ❌ Runtime error during cleanup for session r    u%   ❌ Error during cleanup for session u   🗑️ Removed call session r   r   r   u1   ⚠️ Event loop mismatch when removing session z  - session removed from trackingu    ❌ Error removing call session r   )r   r   r   r   popdebugcleanupr&   r'   r"   r%   r(   r!   r   	traceback	print_exc)r   r   r)   cleanup_errorr+   r*   r1   r   r   r   remove_call_session   s:    
&(*zCallManager.remove_call_sessionc                 C   s   | j |S )zGet an active call session.)r   get)r   r   r   r   r   get_session   s    zCallManager.get_session)r   c                 C   s
   t | jS )zGet number of active sessions.)r!   r   r   r   r   r   get_active_sessions_count   s    z%CallManager.get_active_sessions_countc                 C   s>   t | j| jt | j| j d | jt | j t| j dS )z&Get system-wide status for monitoring.d   )r   r   Zutilization_percentZavailable_slotsZsession_ids)r!   r   r   listkeysr7   r   r   r   get_system_status   s    zCallManager.get_system_statusc                 C   s   dd | j  D S )z"Get status of all active sessions.c                 S   s   i | ]\}}||  qS r   )
get_status).0r   r)   r   r   r   
<dictcomp>  s    z4CallManager.get_session_statuses.<locals>.<dictcomp>)r   itemsr7   r   r   r   get_session_statuses  s    z CallManager.get_session_statusesc           	   
      s  zt | j}td| d g }| j D ]\}}|| || q,|rtj|ddiI dH }dd |D }t |t | }|rt	d| d	t | d
 ntd| d | j
  W n< tk
r } ztd|  | j
  W 5 d}~X Y nX dS )zFCleanup all active sessions (for shutdown) with proper error handling.u   🧹 Cleaning up z active sessionsreturn_exceptionsTNc                 S   s   g | ]}t |tr|qS r   )
isinstancer(   )r>   rr   r   r   
<listcomp>  s     
 z4CallManager.cleanup_all_sessions.<locals>.<listcomp>u   ⚠️ Cleanup completed: z succeeded, z failedu   ✅ All z! sessions cleaned up successfullyu    ❌ Error cleaning up sessions: )r!   r   r   r   r@   append_safe_cleanup_sessionr   gatherr"   clearr(   r%   )	r   Zsession_countZcleanup_tasksr   r)   resultserrorsZ	successesr*   r   r   r   cleanup_all_sessions  s"    
z CallManager.cleanup_all_sessionsc              
      s   z|  I dH  W n tk
rb } z2t|}d|ks<d|krPtd| d n W 5 d}~X Y n: tk
r } ztd| d|   W 5 d}~X Y nX dS )z8Safely cleanup a session with event loop error handling.Nr   r   r-   z - allowing garbage collectionu   ❌ Error cleaning up session r    )r0   r&   r'   r   r"   r(   r%   )r   r)   r   r*   r+   r   r   r   rG   +  s    z!CallManager._safe_cleanup_session)r	   )__name__
__module____qualname____doc__intr   r'   r   r   r   r,   r4   r6   r8   r   r<   rA   rL   rG   r   r   r   r   r      s   ),
r   r	   r
   )rP   r   typingr   r   fastapir   services.log_utilsr   Zservices.call_sessionr   configr   r   call_managerr   r   r   r   <module>   s    -