o
    /i`                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlmZmZmZ d dlm	Z	m
Z
mZmZmZ d dlmZ ddlmZ ddlmZmZ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m Z m!Z!m"Z"m#Z# e	rd dl$m%Z% d dl&m'Z' d dl(m)Z) d dlm*Z* e+dZ,G dd dZ-G dd de-Z.G dd de-Z/G dd de-Z0G dd de-Z1G dd de-Z2G dd de-Z3d$dd d!ee4 fd"d#Z5dS )%    N)datetime	timedeltatimezone)TYPE_CHECKINGAnyOptionalUnioncast)resolve_serializer   )DEFAULT_FAILURE_TTL)AbandonedJobErrorInvalidJobOperationNoSuchJobError)Job	JobStatus)Queue)BaseDeathPenaltyUnixSignalDeathPenalty)as_textbackend_classcurrent_timestampnowparse_composite_key)Redis)Pipeline)	Execution)
Serializerzrq.registryc                   @   s  e Zd ZdZeZeZdZ						dBde	de
d de
ed	  d
e
d de
ede	f  de
ee  fddZdd Zdd ZdedefddZedefddZdCdefddZdDd ed!ed"e
d# d$edef
d%d&ZdEd eee	f d"e
d# d'efd(d)ZdFd*e
e fd+d,ZdGd.ed/ed0ed1edee	 f
d2d3Zd4d5 Zd d	defd6d7Z dHd8ed	e	f d9edd	fd:d;Z!e"d<e	de	fd=d>Z#dId*e
e d?e
e fd@dAZ$dS )JBaseRegistryz
    Base implementation of a job registry, implemented in Redis sorted set.
    Each job is stored as a key in the registry, scored by expiration time
    (unix timestamp).
    zrq:registry:{0}defaultNname
connectionr   	job_classr   queuer   
serializerr   death_penalty_classc                 C   sf   |r|j | _ |j| _|j| _n|| _ || _t|| _| j| j | _|r&|nt| _t	| d|d| _
d S )Nr%   )override)r    r!   r$   r
   key_templateformatkeyr   r"   r   r%   )selfr    r!   r"   r#   r$   r%    r+   K/var/www/html/flask_server/venv/lib/python3.10/site-packages/rq/registry.py__init__(   s   	

zBaseRegistry.__init__c                 C   s   | j S )z+Returns the number of jobs in this registry)countr*   r+   r+   r,   __len__>   s   zBaseRegistry.__len__c                 C   s    | j |j ko| jjj|jjjkS N)r    r!   connection_poolconnection_kwargs)r*   otherr+   r+   r,   __eq__B   s   zBaseRegistry.__eq__itemreturnc                 C   s0   |}t || jr|j}| j| jtt|duS )z
        Returns a boolean indicating registry contains the given
        job instance or job id.

        Args:
            item (Union[str, Job]): A Job ID or a Job.
        N)
isinstancer"   idr!   zscorer)   r	   strr*   r6   job_idr+   r+   r,   __contains__H   s   zBaseRegistry.__contains__c                 C   s   | j ddS )z{Returns the number of jobs in this registry after running cleanup

        Returns:
            int: _description_
        Tcleanup)get_job_countr/   r+   r+   r,   r.   U   s   zBaseRegistry.countTc                 C   s   |r|    | j| jS )zReturns the number of jobs in this registry after optional cleanup.

        Args:
            cleanup (bool, optional): _description_. Defaults to True.

        Returns:
            int: _description_
        )r@   r!   zcardr)   )r*   r@   r+   r+   r,   rA   ^   s   	zBaseRegistry.get_job_countr   Fjobttlpipeliner   xxc                 C   sb   |dk r|nt  | }|dkrd}|dur$tt|j| j|j|i|dS | jj| j|j|i|dS )a  Adds a job to a registry with expiry time of now + ttl, unless it's -1 which is set to +inf

        Args:
            job (Job): The Job to add, or job_id.
            ttl (int, optional): The time to live. Defaults to 0.
            pipeline (Optional['Pipeline'], optional): The Redis Pipeline. Defaults to None.
            xx (bool, optional): .... Defaults to False.

        Returns:
            result (int): The ZADD command result
        r   +infNrF   )r   r	   intzaddr)   r9   r!   )r*   rC   rD   rE   rF   scorer+   r+   r,   addk   s   zBaseRegistry.add
delete_jobc                 C   sj   |dur|n| j }t|| jr|jn|}|| j|}|r3t|| jr&|}n	tj||| jd}|	  |S )aE  Removes job from registry and deletes it if `delete_job == True`

        Args:
            job (Job|str): The Job to remove from the registry, or job_id
            pipeline (Pipeline|None): The Redis Pipeline. Defaults to None.
            delete_job (bool, optional): If should delete the job.. Defaults to False.
        Nr!   r$   )
r!   r8   r"   r9   zremr)   r   fetchr$   delete)r*   rC   rE   rN   r!   r=   resultjob_instancer+   r+   r,   remove   s   zBaseRegistry.remove	timestampc                    s6   |dur|nt  } j jd|} fdd|D S )zReturns job ids whose score are less than current timestamp.

        Returns ids for jobs with an expiry time earlier than timestamp,
        specified as seconds since the Unix epoch. timestamp defaults to call
        time if unspecified.
        Nr   c                       g | ]}  |qS r+   parse_job_id.0r=   r/   r+   r,   
<listcomp>       z4BaseRegistry.get_expired_job_ids.<locals>.<listcomp>r   r!   zrangebyscorer)   )r*   rV   rL   expired_jobsr+   r/   r,   get_expired_job_ids   s   z BaseRegistry.get_expired_job_idsrG   startenddescr@   c                    s0   |r     fdd jj j|||dD S )a  Returns list of all job ids.

        Args:
            start (int, optional): start rank. Defaults to 0.
            end (int, optional): end rank. Defaults to -1.
            desc (bool, optional): sort in reversed order. Defaults to False.
            cleanup (bool, optional): whether to perform the cleanup. Defaults to True.

        Returns:
            List[str]: list of the job ids in the registry
        c                    rW   r+   rX   rZ   r/   r+   r,   r\      r]   z,BaseRegistry.get_job_ids.<locals>.<listcomp>rd   r@   r!   zranger)   r*   rb   rc   rd   r@   r+   r/   r,   get_job_ids   s   $zBaseRegistry.get_job_idsc                 C   s   t | j| j| jdS )z3Returns Queue object associated with this registry.rO   )r   r    r!   r$   r/   r+   r+   r,   	get_queue   s   zBaseRegistry.get_queuec                 C   s    | j | j|j}t|tjS )zkReturns job's expiration time.

        Args:
            job (Job): The Job to get the expiration
        )r!   r:   r)   r9   r   fromtimestampr   utc)r*   rC   rL   r+   r+   r,   get_expiration_time   s   z BaseRegistry.get_expiration_time	job_or_idat_frontc                 C   s   t || jr|}|j}n| j}| jj|| j|d}| j| j|j}|s&t| j	 -}t
|j| j| j|d}d|_d|_d|_|  |j|||d}|  W d   |S 1 s[w   Y  |S )a  Requeues the job with the given job ID.

        Args:
            job_or_id (Union[&#39;Job&#39;, str]): The Job or the Job ID
            at_front (bool, optional): If the Job should be put at the front of the queue. Defaults to False.

        Raises:
            InvalidJobOperation: If nothing is returned from the `ZREM` operation.

        Returns:
            Job: The Requeued Job.
        rO   )r!   r"   r$   N )rE   ro   )r8   r"   r$   rQ   r!   rP   r)   r9   r   rE   r   origin
started_atended_at	_exc_infosave_enqueue_jobexecute)r*   rn   ro   rC   r$   rS   rE   r#   r+   r+   r,   requeue   s(   

zBaseRegistry.requeueentryc                 C   s   t | ts	t| } | S )a  Generic function to retrieve the job id from the stored entry.
        Some Registries might have a different entry format.

        Args:
            entry (str): the entry from the registry

        Returns:
            str: the job_id parsed from the registry.
        )r8   r;   r   )ry   r+   r+   r,   rY      s   
zBaseRegistry.parse_job_idexception_handlersc                 C   s   dS )zThis method is automatically called by `count()` and `get_job_ids()` methods
        implemented in BaseRegistry. Base registry doesn't have any special cleanup instructionsNr+   )r*   rV   rz   r+   r+   r,   r@      s    zBaseRegistry.cleanup)r   NNNNN)Tr   NFNFr1   r   rG   FT)FNN)%__name__
__module____qualname____doc__r   r"   r   r%   r'   r;   r   typer   r   r-   r0   r5   r   boolr>   propertyrJ   r.   rA   rM   rU   floatra   listri   rj   r   rm   rx   staticmethodrY   r@   r+   r+   r+   r,   r      sP    


$$$ 	" r   c                   @   s8  e Zd ZdZdZd+dee dee fddZd,d
dddde	de
de	f
ddZ				d-d
ddee ded de
ddf
ddZ	d.de	de	de
de
deeeef  f
ddZdede
fd d!Zd/dede	ded de
de	f
d"d#Zd0deeef ded de
fd$d%Zed&edefd'd(Zd1deded ddfd)d*ZdS )2StartedJobRegistryaM  
    Registry of currently executing jobs. Each queue maintains a
    StartedJobRegistry. Jobs in this registry are ones that are currently
    being executed.

    Jobs are added to registry right before they are executed and removed
    right after completion (success or failure).

    Each entry is a {job_id}:{execution_id}
    z
rq:wip:{0}NrV   rz   c              
   C   s|  |dur|nt  }| |}|r|  }| j }|D ]}z| jj|| j| jd}W n	 ty4   Y qw |	| j
tt t  |r\|D ]}	|	|tt t }
|
du rWd}
|
s[ nqE|joc|jdk}|rm||| qdtj dtj dt  }td| jj|j| |jtj|d	 |j||d
d |j|dd q|| jd| |  W d   dS 1 sw   Y  dS dS )a  Remove abandoned jobs from registry and add them to FailedJobRegistry.

        Removes jobs with an expiry time earlier than timestamp, specified as
        seconds since the Unix epoch. timestamp defaults to call time if
        unspecified. Removed jobs are added to the global failed job queue.

        Args:
            timestamp (datetime): The datetime to use as the limit.
        NrO   Tr   z	Moved to z	, due to z, at z%s cleanup: %s %srE   rp   )worker_nameF)refresh_job_status)r   ra   rj   r!   rE   r"   rQ   r$   r   execute_failure_callbackr%   r   	tracebackextract_stackretries_leftretryFailedJobRegistryr   r   loggerwarning	__class__r9   
set_statusr   FAILED_handle_failureenqueue_dependentszremrangebyscorer)   rw   )r*   rV   rz   rL   job_idsr#   rE   r=   rC   handlerfallthroughr   
exc_stringr+   r+   r,   r@      sJ   


"zStartedJobRegistry.cleanupr   F	executionr   rE   r   rD   rF   r7   c                 C   s:   |dk r|nt  | }|dkrd}|j| j|j|i|dS )a  Adds an execution to a registry with expiry time of now + ttl, unless it's -1 which is set to +inf

        Args:
            execution (Execution): The Execution to add.
            pipeline (Pipeline): The Redis Pipeline.
            ttl (int, optional): The time to live. Defaults to 0.
            xx (bool, optional): .... Defaults to False.

        Returns:
            result (int): The ZADD command result
        r   rG   rH   rI   )r   rK   r)   composite_key)r*   r   rE   rD   rF   rL   r+   r+   r,   add_execution8  s   z StartedJobRegistry.add_executionrC   rN   c                 C   s&   |dur|n| j }|| j|j dS )a  Removes job from registry and deletes it if `delete_job == True`

        Args:
            execution (Execution): The Execution to remove
            job (Optional[Job]): The Job to remove from the registry
            pipeline (Optional['Pipeline'], optional): The Redis Pipeline. Defaults to None.
            delete_job (bool, optional): If should delete the job.. Defaults to False.
        N)r!   rP   r)   r   )r*   r   rC   rE   rN   r!   r+   r+   r,   remove_executionJ  s   z#StartedJobRegistry.remove_executionrG   Trb   rc   rd   r@   c                 C   s,   |r|    dd | jj| j|||dD S )aH  Function to retrieve a list of tuples where the first item is the job id and
            the second is the execution id.

        Args:
            start (int, optional): start rank. Defaults to 0.
            end (int, optional): end rank. Defaults to -1.
            desc (bool, optional): sort in reversed order. Defaults to False.
            cleanup (bool, optional): whether to perform the cleanup. Defaults to True.

        Returns:
            List[Tuple[str, str]]: a list of tuples where the first item is the job id and
            the second is the execution id.
        c                 S   s   g | ]}t t|qS r+   )r   r   )r[   ry   r+   r+   r,   r\   p  s    z@StartedJobRegistry.get_job_and_execution_ids.<locals>.<listcomp>re   rf   rh   r+   r+   r,   get_job_and_execution_ids^  s
   z,StartedJobRegistry.get_job_and_execution_idsr6   c                 C   s,   |}t || jr|j}tt|| jddv S )zMethod to check if the item is in the registry.

        Args:
            item (Any): Either a Job (instance of job_class) or a job id.

        Returns:
            bool: True if the item is in the registry.
        Fr?   )r8   r"   r9   r	   r;   ri   r<   r+   r+   r,   r>   t  s   	zStartedJobRegistry.__contains__c                 C      t  r1   NotImplementedErrorr*   rC   rD   rE   rF   r+   r+   r,   rM        zStartedJobRegistry.addc                 C   r   r1   r   )r*   rC   rE   rN   r+   r+   r,   rU     r   zStartedJobRegistry.removery   c                 C   s"   t | ts	t| } t| \}}|S r1   )r8   r;   r   r   )ry   r=   _execution_idr+   r+   r,   rY     s   
zStartedJobRegistry.parse_job_idc                 C   sD   |dur|n| j }dd | D }|r |j| jg|R   dS dS )zRemoves job executions from the started job registry.

        Args:
            job (Job): The Job to remove from the registry
            pipeline (Optional['Pipeline']): The Redis Pipeline. Defaults to None.
        Nc                 S   s   g | ]}|j qS r+   )r   )r[   r   r+   r+   r,   r\     s    z8StartedJobRegistry.remove_executions.<locals>.<listcomp>)r!   get_executionsrP   r)   )r*   rC   rE   r!   execution_idsr+   r+   r,   remove_executions  s
   z$StartedJobRegistry.remove_executionsr~   )r   FNNFr}   r{   r|   r1   )r   r   r   r   r'   r   r   r   r@   rJ   r   r   r   r   tupler;   r   r   r>   rM   r   rU   r   rY   r   r+   r+   r+   r,   r      sJ     9

$$ r   c                   @   s0   e Zd ZdZdZddee dee fddZdS )	FinishedJobRegistryz
    Registry of jobs that have been completed. Jobs are added to this
    registry after they have successfully completed for monitoring purposes.
    zrq:finished:{0}NrV   rz   c                 C   (   |dur|nt  }| j| jd| dS zRemove expired jobs from registry.

        Removes jobs with an expiry time earlier than timestamp, specified as
        seconds since the Unix epoch. timestamp defaults to call time if
        unspecified.
        Nr   r   r!   r   r)   r*   rV   rz   rL   r+   r+   r,   r@        zFinishedJobRegistry.cleanupr~   )	r   r   r   r   r'   r   r   r   r@   r+   r+   r+   r,   r     s     r   c                   @   sR   e Zd ZdZdZddee dee fddZ			dd	d
de	ded fddZ
dS )r   z-
    Registry of containing failed jobs.
    zrq:failed:{0}NrV   rz   c                 C   r   r   r   r   r+   r+   r,   r@     r   zFailedJobRegistry.cleanuprp   rC   r   r   rE   r   c                 C   s   |du rt }|dk r|nt | }|r|}n| j }||_|j|ddd |j||d || j|j	|i |s?|
  dS dS )z
        Adds a job to a registry with expiry time of now + ttl.
        `ttl` defaults to DEFAULT_FAILURE_TTL if not specified.
        Nr   F)rE   include_metainclude_result)rD   rE   )r   r   r!   rE   rt   ru   r@   rK   r)   r9   rw   )r*   rC   rD   r   rE   rL   pr+   r+   r,   rM     s   
zFailedJobRegistry.addr~   )Nrp   N)r   r   r   r   r'   r   r   r   r@   r;   rM   r+   r+   r+   r,   r     s    r   c                       s`   e Zd ZdZdZddee dee fddZdd	e	d
ee
 ded dede
f
 fddZ  ZS )DeferredJobRegistryzH
    Registry of deferred jobs (waiting for another job to finish).
    zrq:deferred:{0}NrV   rz   c           	   
   C   s   |dur|nt  }| |}|re| j F}|D ].}z| jj|| j| jd}W n	 ty0   Y qw |jt	j
|d dt }|j||dd q|| jd| |  W d   dS 1 s^w   Y  dS dS )a,  Remove expired jobs from registry and add them to FailedJobRegistry.
        Removes jobs with an expiry time earlier than timestamp, specified as
        seconds since the Unix epoch. timestamp defaults to call time if
        unspecified. Removed jobs are added to the failed job registry.
        NrO   r   z>Expired in DeferredJobRegistry, moved to FailedJobRegistry at rp   )r   rE   r   r   )r   ra   r!   rE   r"   rQ   r$   r   r   r   r   r   r   r   r)   rw   )	r*   rV   rz   rL   r   rE   r=   rC   exc_infor+   r+   r,   r@     s"   


"zDeferredJobRegistry.cleanupFrC   rD   rE   r   rF   r7   c                    s"   |du rd}t t| ||||S )zp
        Adds a job to a registry with expiry time of now + ttl.
        Defaults to -1 (never expire).
        NrG   )superr   rM   r   r   r+   r,   rM     s   zDeferredJobRegistry.addr~   r   )r   r   r   r   r'   r   r   r   r@   r   rJ   r   rM   __classcell__r+   r+   r   r,   r     s
    4r   c                       s   e Zd ZdZdZ fddZdddded	 fd
dZddee ded	 fddZ	ddee dede
e fddZdedef defddZ  ZS )ScheduledJobRegistryz%
    Registry of scheduled jobs.
    zrq:scheduled:{0}c                    s   t  j|i | | j| _d S r1   )r   r-   ra   get_jobs_to_enqueue)r*   argskwargsr   r+   r,   r-     s   zScheduledJobRegistry.__init__NrC   r   rE   r   c                 C   sX   |j stttjdkrtjntj d}|j|d}t|	 }| j
| j|j|iS )z
        Adds job to registry, scored by its execution time (in UTC).
        If datetime has no tzinfo, it will assume local timezone.
        r   )seconds)tzinfo)r   r   r   timedaylightaltzonereplacecalendartimegmutctimetupler!   rK   r)   r9   )r*   rC   scheduled_datetimerE   tzrV   r+   r+   r,   schedule  s
   "zScheduledJobRegistry.schedulerV   c                 C   s@   t dt |dur|n| j}|dur|nt }|| jd|S )a   Remove jobs whose timestamp is in the past from registry.

        Args:
            timestamp (Optional[int], optional): The timestamp. Defaults to None.
            pipeline (Optional['Pipeline'], optional): The Redis pipeline. Defaults to None.
        zSScheduledJobRegistry.remove_jobs() is deprecated and will be removed in the future.Nr   )warningswarnDeprecationWarningr!   r   r   r)   )r*   rV   rE   r!   rL   r+   r+   r,   remove_jobs$  s   z ScheduledJobRegistry.remove_jobs  
chunk_sizer7   c                 C   s8   |dur|nt  }| jj| jd|d|d}dd |D S )a  Get's a list of job IDs that should be scheduled.

        Args:
            timestamp (Optional[int]): _description_. Defaults to None.
            chunk_size (int, optional): _description_. Defaults to 1000.

        Returns:
            jobs (List[str]): A list of Job ids
        Nr   )rb   numc                 S   s   g | ]}t |qS r+   )r   rZ   r+   r+   r,   r\   >  s    z=ScheduledJobRegistry.get_jobs_to_schedule.<locals>.<listcomp>r^   )r*   rV   r   rL   jobs_to_scheduler+   r+   r,   get_jobs_to_schedule2  s   
z)ScheduledJobRegistry.get_jobs_to_schedulern   c                 C   s>   t |tr	|j}n|}| j| j|}|sttj|t	j
dS )a:  Returns datetime (UTC) at which job is scheduled to be enqueued

        Args:
            job_or_id (Union[Job, str]): The Job instance or Job ID

        Raises:
            NoSuchJobError: If the job was not found

        Returns:
            datetime (datetime): The scheduled time as datetime object
        )r   )r8   r   r9   r!   r:   r)   r   r   rk   r   rl   )r*   rn   r=   rL   r+   r+   r,   get_scheduled_time@  s   
z'ScheduledJobRegistry.get_scheduled_timer1   r~   )Nr   )r   r   r   r   r'   r-   r   r   rJ   r   r   r;   r   r   r   r   r   r+   r+   r   r,   r   	  s     "r   c                   @   s$   e Zd ZdZddee fddZdS )CanceledJobRegistryzrq:canceled:{0}NrV   c                 C   s   t r1   r   )r*   rV   r+   r+   r,   ra   [  s   z'CanceledJobRegistry.get_expired_job_idsr1   )r   r   r   r'   r   r   ra   r+   r+   r+   r,   r   X  s    r   r#   r   rz   c                 C   sx   t | j| j| j| jd  t| j| j| j| jdj|d t| j| j| j| jd  t| j| j| j| jd  dS )zCleans StartedJobRegistry, FinishedJobRegistry and FailedJobRegistry, and DeferredJobRegistry of a queue.

    Args:
        queue (Queue): The queue to clean
    )r    r!   r"   r$   )rz   N)	r   r    r!   r"   r$   r@   r   r   r   )r#   rz   r+   r+   r,   clean_registries_  s"   
r   r1   )6r   loggingr   r   r   r   r   r   typingr   r   r   r   r	   rq.serializersr
   defaultsr   
exceptionsr   r   r   rC   r   r   r#   r   timeoutsr   r   utilsr   r   r   r   r   redisr   redis.clientr   rq.executionsr   r   	getLoggerr   r   r   r   r   r   r   r   r   r   r+   r+   r+   r,   <module>   s<    
 U ..*O