
    	]j&                        d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	Z	ddl
Z
ddlmZ ddlmZ ddl	mZ dd	lmZ dd
lmZ ddlmZ  ej,                  e      Zd dZ	  e       Zej7                          ej9                  d       d Zd ZdedefdZ de!fdZ"d Z#d Z$d!dZ%d Z&d Z'dddZ(d Z)d Z*d Z+d Z,y#  ej9                  d       dZY NxY w)"zThis file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
    N)	timedelta)partial)Any)CurrentContext)settings)get_connection)send_stop_job_command)InvalidJobOperation)StartedJobRegistryc                 ^  
 	 fd

fd}| D cg c]
  } ||       }}|j                         D ci c]  \  }}|dk7  s| ||       }}}g }	|r|	j                  d|        |r|	j                  d|        |	rdj                  |	      S dS c c}w c c}}w # t        $ r Y yw xY w)	Nc                 N    t        |       }|d  t        |      kD  rdz   S dz   S )Nz... )reprlen)valuev_repr
max_lengths     A/root/env/lib/python3.12/site-packages/label_studio/core/redis.py_truncate_scalarz4_truncate_args_for_logging.<locals>._truncate_scalar   s2    %[F+:&3v;3K%TTQSTT    c                     t        | t              rVg }| j                         D ]*  \  }}|j                  t	        |       d |              , ddj                  |      z   dz   S  |       S )Nz: {, })
isinstancedictitemsappendr   join)r   partsdkdvr   s       r   _truncate_top_levelz7_truncate_args_for_logging.<locals>._truncate_top_level   su    %&#kkm HFBLLDH:R0@0D/E!FGH TYYu--33#E**r   
on_failurezargs: zkwargs: r   zno argumentszfailed to format arguments)r   r   r   	Exception)argskwargsr   r#   argtruncated_argskvtruncated_kwargsresultr   s     `       @r   _truncate_args_for_loggingr.      s    ,	U	+ ?CCs-c2CCBH,,.f$!QTUYeTeA2155ffMMF>"234MMH%5$678$*tyy >> Df  ,+,s9   B  BB  BBAB  B  B   	B,+B,z#=> Redis is connected successfully.z=> Redis is not connected.c                     t         sy	 t         j                          t        j                  d       y# t        j
                  j                  $ r$} t        j                  d|  d       Y d } ~ yd } ~ wt        j
                  j                  $ r$} t        j                  d|  d       Y d } ~ yd } ~ wt        j
                  j                  $ r$} t        j                  d|  d       Y d } ~ yd } ~ ww xY w)NFzRedis client is alive!Tz/Redis healthcheck failed with ConnectionError: )exc_infoz,Redis healthcheck failed with TimeoutError: zRedis healthcheck failed: )
_redispingloggerdebugredis
exceptionsConnectionErrorerrorTimeoutError
RedisError)excs    r   redis_healthcheckr<   >   s     	-. ++ FseLW[\(( CC5ITXY&& 1#7$Gs-   3 C2A// C2B.. C2C--C2c                  8    t         j                  r
t               S y)NF)r   REDIS_ENABLEDr<    r   r   redis_connectedr@   Q   s     ""r   r   returnc                 j    t        | t        t        t        t        t
        t        t        d      f      S )z3Check if a value can be serialized for job context.N)r   strintfloatboollistr   type)r   s    r   _is_serializablerI   W   s"    ec3tT4dLMMr   c                  d   i } t        j                         x}r|j                  | d<   t        j                         x}r|| d<   |s)|r't	        |d      r|j
                  r|j
                  | d<   t        j                         }|j                         D ]  \  }}|dvst        |      s|| |<    | S )z|
    Capture the current context for passing to a job.
    Returns a dictionary of context data that can be serialized.
    user_idorganization_idactive_organization_id)userrequest)	r   get_useridget_organization_idhasattrrM   get_job_datar   rI   )context_datarN   org_idjob_datakeyr   s         r   _capture_contextrY   \   s    
 L &&((t("&''Y  3355v5*0&' dwt-EF4KfKf*.*E*E&' **,Hnn& &
U)).>u.E %L& r   c                 B    t               sy t        j                  |       S N)r<   r1   getrX   s    r   	redis_getr^   y   s    ::c?r   c                 D    t               sy t        j                  | |      S r[   )r<   r1   hget)key1key2s     r   
redis_hgetrc      s    ;;tT""r   c                 H    t               sy t        j                  | ||      S )N)ex)r<   r1   set)rX   r   ttls      r   	redis_setrh      s     ::c5S:))r   c                 F    t               sy t        j                  | ||      S r[   )r<   r1   hset)ra   rb   r   s      r   
redis_hsetrk      s    ;;tT5))r   c                 B    t               sy t        j                  |       S r[   )r<   r1   deleter]   s    r   redis_deletern      s    ==r   )
in_secondsc          	         ddl m} t               xr |j                  dd      }|j                  dd      }d|v r|d= d|v r|d= d}d|v r|d   }|d= d}d	|v r!|d	   }|d	= t	        |t
              r	 ||
      }|j                  dd      }	|r	 t               }
|j                  di       }|j                  |
       ||d<   	 t        ||      }t        j                  d| j                   d| d| d       t        j                  |      }|j                   }|dkD  r t#        |j$                  t'        |            } || g|i ||t(        j*                  ||	d} | S 	  | |i |}|S # t        $ r( t        j                  d| j                   d|        Y w xY w# t        $ r) t        j                  d| j                   d| d       Y w xY w# t        $ r! t-        j.                         }|	r	 |	| g|   w xY w)a  
    Start job async with redis or sync if redis is not connected.
    Automatically preserves context for async jobs and clears it after completion.

    :param job: Job function
    :param args: Function arguments
    :param in_seconds: Job will be delayed for in_seconds
    :param retry: RQ Retry object or int (max retries). Only used in async mode.
    :param kwargs: Function keywords arguments
    :return: Job or function result
    r   )Retryr5   T
queue_namedefaultNjob_timeoutretry)maxr$   metaz"Failed to capture context for job z
 on queue zStart async job z with .)seconds)rt   failure_ttlru   r$   )rqrq   r@   r\   r   rD   poprY   updater%   r3   info__name__r.   	django_rq	get_queueenqueuer   
enqueue_inr   r   RQ_FAILED_JOB_TTLsysr0   )jobro   r&   r'   rq   r5   rr   rt   ru   r$   rU   rw   	args_infoqueueenqueue_methodr-   r0   s                    r   start_job_async_or_syncr      sC    ;&**Wd";EL)4Jv< &7OK]+=!E&w7OeS!e$EL$/J	c+-L::fb)DKK%!F6N	R24@IKK*3<<.
:,fU^T__`ab ##J/>$U%5%5y7TUN

 
 $ 22!
 
	$)&)FM5  	cKK<S\\N*U_T`ab	c  	RKK*3<<.
:,aPQ	R*  	||~H3**		s0   2E+ 5F !	G +.FF/GG*G>c                 2    t        | ||      }t        |      S )z
    Checks if func_name with kwargs[meta] is in queue (doesn't check workers)
    :param queue: queue object
    :param func_name: function name
    :param meta: job meta information
    :return: True if job in queue
    )get_jobs_by_metaany)r   	func_namerw   jobss       r   is_job_in_queuer      s     E9d3Dt9r   c                     | syt        |t              }t        | t              r| j	                         n| }|j
                  j                  |j                  |      duS )z
    Checks if job id is on workers
    :param job_id: Job ID
    :param queue_name: Queue name
    :return: True if job on worker
    F)
connectionN)r   r1   r   rC   encoder   zscorerX   )job_idrr   registrymembers       r   is_job_on_workerr      sP     !*@H *63 7V]]_VF %%hllF;4GGr   c           	      P   | j                  |      }|at        j                  d| d| j                   d       	 |j	                          |j                          t        j                  d| d       yt        j                  d| d	| j                   d       	 t        t        |       t        j                  d
| d       y# t        $ r t        j                  d| d       Y yw xY w# t        $ r.}t        j                  d| dt        |              Y d}~yd}~ww xY w)zk
    Delete job by id from queue
    @param queue: Queue on redis to delete from
    @param id: Job id
    NzStopping job z from queue rx   zFetched job z and stopped.zJob z was already cancelled.z on worker from queue zSend stop job z to redis worker.z
Redis job z was not found: )	fetch_jobr3   r~   namecancelrm   r4   r
   r	   r1   r%   rC   )r   rQ   r   es       r   delete_job_by_idr     s    //"
C
mB4|EJJ<qAB	=JJLJJLLL<t=9:
 	mB4'=ejj\KL	D!&"-LL>"->?@ # 	=LL4t#:;<	=  	DLL:bT)9#a&BCC	Ds)   9C )C. "C+*C+.	D%7$D  D%c                     fd| j                         D        }|D cg c]!  }t        |d      s|j                  |k(  s |# c}S c c}w )z
    Get jobs from queue by func_name and meta data
    :param queue: Queue on redis to check in
    :param func_name: Started function name
    :param meta: meta dict
    :return: Job list
    c              3   V   K   | ]   }|j                   j                  k(  s| " y wr[   )funcr   ).0r   r   s     r   	<genexpr>z#get_jobs_by_meta.<locals>.<genexpr>*  s"     NCsxx/@/@I/MCNs   ))rw   )get_jobsrS   rw   )r   r   rw   r   r   s    `   r   r   r   !  s?     O5>>+NDMC73#7CHH<LCMMMs   AAA)   r[   )-__doc__loggingr   datetimer   	functoolsr   typingr   r   r5   core.current_requestr   django.confr   r   
rq.commandr	   rq.exceptionsr
   rq.registryr   	getLoggerr   r3   r.   r1   r2   r4   r<   r@   rF   rI   r   rY   r^   rc   rh   rk   rn   r   r   r   r   r   r?   r   r   <module>r      s     
      /   $ , - *			8	$,@F
KKM
LL67&NC ND N
$ :#** 45 L^H&D4NQ
LL-.Fs    (B? ?C