o
    i!                     @   s   d dl Z d dlmZmZ d dlmZmZmZ d dlmZ d dl	m
Z
 er0d dlmZ ddl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 G dd dZG dd deZe dZdddedefddZdddeddddfddZdS )    N)datetimetimezone)TYPE_CHECKINGAnyOptional)uuid4)Redis)Pipeline   )
BaseWorker)Job)BaseRegistryStartedJobRegistry)as_textcurrent_timestampnowparse_composite_keyc                	   @   s  e Zd ZdZdededefddZdedefd	d
Z	e
defddZe
defddZe
dd Zededededd fddZdd Zedededd fddZedededddd fddZd(deded fdd Zdeddfd!d"Zdefd#d$Zd%ededdfd&d'ZdS ))	Executionz)Class to represent an execution of a job.idjob_id
connectionc                 C   s.   || _ || _|| _t }|| _|| _d | _d S N)r   r   r   r   
created_atlast_heartbeat_job)selfr   r   r   Z	right_now r   D/home/app/Keep/.python/lib/python3.10/site-packages/rq/executions.py__init__   s   
zExecution.__init__otherreturnc                 C   s   t |tsdS | j|jkS )NF)
isinstancer   r   )r   r   r   r   r   __eq__   s   
zExecution.__eq__c                 C   s   d| j  S )Nzrq:execution:)composite_keyr   r   r   r   key$   s   zExecution.keyc                 C   s&   | j r| j S tj| j| jd| _ | j S )N)r   r   )r   r   fetchr   r   r$   r   r   r   job(   s   zExecution.jobc                 C   s   | j  d| j S )N:)r   r   r$   r   r   r   r#   /   s   zExecution.composite_keyc                 C   s   | |||d}|   |S )zFetch an execution from Redis.r   r   r   )refresh)clsr   r   r   	executionr   r   r   r&   3   s   zExecution.fetchc                 C   s\   | j | j}|std| j dtjt|d tj	d| _
tjt|d tj	d| _dS )z"Refresh execution data from Redis.z
Execution z not found in Rediss
   created_at)tzs   last_heartbeatN)r   Zhgetallr%   
ValueErrorr   r   fromtimestampfloatr   utcr   r   )r   datar   r   r   r*   :   s
   zExecution.refreshr#   c                 C   s   t |\}}| |||dS )z>A combination of job_id and execution_id separated by a colon.r)   )r   )r+   r#   r   r   execution_idr   r   r   from_composite_keyB   s   zExecution.from_composite_keyr'   ttlpipeliner	   c                 C   sZ   t  j}| ||j|jd}|j||d t|j|dj|||d |jj|||dd |S )zSave execution data to Redis.r)   )r5   r6   r   r   r,   r5   r6   F)r6   r5   xx)	r   hexr   r   saveExecutionRegistryaddstarted_job_registryadd_execution)r+   r'   r5   r6   r   r,   r   r   r   createH   s   zExecution.createNc                 C   s8   |dur|n| j }|j| j|  d || j| dS )z6Save execution data to Redis and JobExecutionRegistry.N)mapping)r   hsetr%   	serializeexpire)r   r5   r6   r   r   r   r   r;   R   s   zExecution.savec                 C   s:   | | j |jj| |d t| j| jdj| |d dS )zDelete an execution from Redis.)r,   r6   r7   N)deleter%   r>   Zremove_executionr<   r   r   remove)r   r'   r6   r   r   r   rE   Y   s   zExecution.deletec                 C   s   | j | j | j dS )N)r   r   r   )r   r   	timestampr   r$   r   r   r   rC   _   s   zExecution.serializer>   c                 C   s\   t  | _|| jd| j  || j| |j| ||dd t| j|dj	| ||d dS )zUpdate execution heartbeat.r   T)r5   r6   r9   r7   r8   N)
r   r   rB   r%   rG   rD   r?   r<   r   r=   )r   r>   r5   r6   r   r   r   	heartbeatf   s
   zExecution.heartbeatr   )__name__
__module____qualname____doc__strr   r   objectboolr"   propertyr%   r   r'   r#   classmethodr&   r*   r4   intr@   r   r;   rE   dictrC   r   rH   r   r   r   r   r      s*    	
	r   c                   @   s   e Zd ZdZdZdedefddZd dee	 d	ee
 fd
dZdededddefddZdedddefddZd!dedede
e fddZd!dedede
e fddZdeddfddZdS )"r<   zbClass to represent a registry of job executions.
    Each job has its own execution registry.
    zrq:executions:{0}r   r   c                 C   s   || _ || _| j|| _d S r   )r   r   key_templateformatr%   )r   r   r   r   r   r   r   w   s   zExecutionRegistry.__init__NrG   exception_handlersc                 C   s(   |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   Zzremrangebyscorer%   )r   rG   rV   scorer   r   r   cleanup|   s   zExecutionRegistry.cleanupr,   r5   r6   r	   r    c                 C   s8   t  | }|| j|j|d i || j|d  dS )a  Register an execution to registry with expiry time of now + ttl, unless it's -1 which is set to +inf

        Args:
            execution (Execution): The Execution to add
            ttl (int, optional): The time to live. Defaults to 0.
            pipeline (Optional[Pipeline], optional): The Redis Pipeline. Defaults to None.

        Returns:
            result (int): The ZADD command result
        <   N)r   Zzaddr%   r   rD   )r   r,   r5   r6   rW   r   r   r   r=      s   
zExecutionRegistry.addc                 C   s   | | j|jS )z"Remove an execution from registry.)Zzremr%   r   )r   r,   r6   r   r   r   rF      s   zExecutionRegistry.remover   startendc                 C   s$   |    dd | j| j||D S )&Returns all executions IDs in registryc                 S   s   g | ]}t |qS r   )r   ).0r   r   r   r   
<listcomp>   s    z7ExecutionRegistry.get_execution_ids.<locals>.<listcomp>)rX   r   Zzranger%   )r   r[   r\   r   r   r   get_execution_ids   s   z#ExecutionRegistry.get_execution_idsc                 C   s8   |  ||}g }|D ]}|tj|| j| jd q
|S )r]   r)   )r`   appendr   r&   r   r   )r   r[   r\   Zexecution_ids
executionsr3   r   r   r   get_executions   s
   z ExecutionRegistry.get_executionsr'   c                 C   s0   |   }|D ]	}|j||d q|| j dS )zDelete the registry.)r6   r'   N)rc   rE   r%   )r   r'   r6   rb   r,   r   r   r   rE      s   zExecutionRegistry.delete)NN)r   rZ   )rI   rJ   rK   rL   rT   rM   r   r   r   r0   listrX   r   rR   r   r=   rF   r`   rc   r   rE   r   r   r   r   r<   p   s    
	r<   z	rq.workerworkerr   r'   r    c                 C   st   ddl m} | j $}| |}tj|||d| _| j|j	|d |
  W d   | jS 1 s2w   Y  | jS )az  Prepares execution for a job. This is called by the main Worker (not the horse)
    as it prepares for execution. Do not confuse this with worker.prepare_job_execution()
    which is called by the horse.

    Args:
        worker: The worker preparing the execution
        job: The job to prepare execution for

    Returns:
        Execution: The created Execution object
    r
   )WorkerStatusr6   N)worker.baserf   r   r6   Zget_heartbeat_ttlr   r@   r,   Z	set_stateZBUSYexecute)re   r'   rf   r6   Zheartbeat_ttlr   r   r   prepare_execution   s   


rj   r6   r	   c                 C   sD   t d|j | jd|d | jdur | jj||d d| _dS dS )a@  Cleans up the execution of a job.
    It will remove the job execution record from the StartedJobRegistry and delete the Execution object.

    Args:
        worker: The worker to clean up execution for
        job: The job whose execution is being cleaned up
        pipeline: Redis pipeline to use for the cleanup
    zCleaning up execution of job %sNrg   )r'   r6   )loggerdebugr   Zset_current_job_idr,   rE   )re   r'   r6   r   r   r   cleanup_execution   s   	

rm   )loggingr   r   typingr   r   r   uuidr   Zredisr   Zredis.clientr	   rh   r   r'   r   registryr   r   utilsr   r   r   r   r   r<   	getLoggerrk   rj   rm   r   r   r   r   <module>   s     ]
A