o
    Ti7+                     @   s$  d dl mZ d dlmZmZ d dlmZ d dlmZ d dl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 d dlmZ d dlmZ eeZdddZG dd dZG dd de Z!G dd de Z"G dd de Z#eG dd de Z$e! Z%dd Z&dS )    )unicode_literals)datetime	timedelta)import_module)
ThreadPoolN)apps)OperationalError)timezone)python_2_unicode_compatible)BackgroundTaskError)Task)app_settings)signalsc              
   O   s^  t jt zit| dd}t|tr| \}}n#t| dd}t| dd}tjj|||d}|r6|j	|d}|r<|d }|du rDt
d||i | |rn|  | }t jj|j|j|d	 |  |  td
| W n7 ty }	 z+t \}
}}|rtjd||
||fd t jj|	j|d ||
|| ~W Y d}	~	nd}	~	ww t jt dS )z
    Executes the function attached to task. Used to enable threads.
    If a Task instance is provided, args and kwargs are ignored and retrieved from the Task itself.
    task_functionNnamequeue)	task_nameargskwargsr   r   z Function is None, can't execute!)sendertask_idZcompleted_taskzRan task and deleting %s
zRescheduling %s
)exc_infor   task)r   Ztask_startedsendr   getattr
isinstanceparamsobjectsZget_taskfilterr   Zincrement_attemptsZcreate_completed_taskZtask_successful	__class__idZcreate_repetitiondeleteloggerinfo	Exceptionsysr   errorZ
task_errorZ
rescheduleZtask_finished)
proxy_taskr   r   r   funcr   Z
task_queueZtask_qs	completedexte	traceback r0   U/var/www/html/evchargy.com/venv/lib/python3.10/site-packages/background_task/tasks.py	bg_runner   sB   
r2   c                   @   s2   e Zd Zdd ZdZedd ZdddZeZdS )	
PoolRunnerc                 C   s   || _ || _d S N)
_bg_runner_num_processes)selfr2   Znum_processesr0   r0   r1   __init__B   s   
zPoolRunner.__init__Nc                 C   s   | j s
t| jd| _ | j S )N)Z	processes)_pool_instancer   r6   r7   r0   r0   r1   _poolH   s   zPoolRunner._poolc                 O   s$   | j j| j||ft| |d d S )N)r*   r   kwds)r;   Zapply_asyncr5   tuple)r7   r)   r   r   r   r0   r0   r1   runN   s   $zPoolRunner.runr4   )	__name__
__module____qualname__r8   r9   propertyr;   r>   __call__r0   r0   r0   r1   r3   A   s    

r3   c                   @   s6   e Zd Zdd Z		dddZdddZdd	d
ZdS )Tasksc                 C   s,   i | _ t | _t| _t| _tttj	| _
d S r4   )_tasksDBTaskRunner_runner	TaskProxy_task_proxy_classr2   r5   r3   r   ZBACKGROUND_TASK_ASYNC_THREADS_pool_runnerr:   r0   r0   r1   r8   U   s
   zTasks.__init__NFc                    s<   d} rt  r }d  fdd}|r||S |S )z
        decorator to turn a regular function into
        something that gets run asynchronously in
        the background, at a later time
        Nc                    s<    }|sd| j | jf }|| j}|j|< |S )Nz%s.%s)r@   r?   rI   rG   rE   )fn_nameproxyr   r   remove_existing_tasksscheduler7   r0   r1   
_decoratork   s   
z$Tasks.background.<locals>._decorator)callable)r7   r   rP   r   rO   rK   rQ   r0   rN   r1   
background\   s   
zTasks.backgroundc                 C   sn   t |tr|}|j}g }i }nd }| j| }tjr(| j||g|R i | d S | j||g|R i | d S r4   )r   r   r   rE   r   ZBACKGROUND_TASK_RUN_ASYNCrJ   r5   )r7   r   r   r   r   r)   r0   r0   r1   run_taskx   s   

zTasks.run_taskc                 C   s   | j | |S r4   )rG   run_next_task)r7   r   r0   r0   r1   rU      s   zTasks.run_next_task)NNNF)NNr4   )r?   r@   rA   r8   rS   rT   rU   r0   r0   r0   r1   rD   T   s    

rD   c                   @   sj   e Zd ZdZdZdZdddZedd Zd	d
 Z	e
dd Ze
dd Ze
dd Zdd Zdd ZdS )TaskScheduler         Nc                 C   s   || _ || _|| _d S r4   _run_at	_priority_action)r7   run_atpriorityactionr0   r0   r1   r8      s   
zTaskSchedule.__init__c                 C   sf   t |tr|S d }d }d }|r,t |tttfr|}n|dd }|dd }|dd }t|||dS )Nr]   r^   r_   r]   r^   r_   )r   rV   intr   r   get)r7   rP   r^   r]   r_   r0   r0   r1   create   s   
zTaskSchedule.createc                 C   sR   i }dD ]}d| }t | |d }|d u rt ||d ||< q|||< qtdi |S )Nr`   z_%sr0   )r   rV   )r7   rP   r   r   Z	attr_namevaluer0   r0   r1   merge   s   
zTaskSchedule.mergec                 C   sD   | j pt }t|trt t|d }t|tr t | }|S )N)seconds)rZ   r	   nowr   ra   r   )r7   r]   r0   r0   r1   r]      s   

zTaskSchedule.run_atc                 C   s
   | j pdS )Nr   )r[   r:   r0   r0   r1   r^      s   
zTaskSchedule.priorityc                 C   s   | j ptjS r4   )r\   rV   SCHEDULEr:   r0   r0   r1   r_      s   zTaskSchedule.actionc                 C   s   d| j | jf S )Nz$TaskSchedule(run_at=%s, priority=%s))rZ   r[   r:   r0   r0   r1   __repr__   s   zTaskSchedule.__repr__c                 C   s$   | j |j ko| j|jko| j|jkS r4   rY   )r7   otherr0   r0   r1   __eq__   s
   

zTaskSchedule.__eq__)NNN)r?   r@   rA   rh   RESCHEDULE_EXISTINGCHECK_EXISTINGr8   classmethodrc   re   rB   r]   r^   r_   ri   rk   r0   r0   r0   r1   rV      s     




rV   c                	   @   sR   e Zd ZdZdd Zddejddddddf	ddZdd	d
Zdd Z	dddZ
dS )rF   zt
    Encapsulate the model related logic in here, in case
    we want to support different queues in the future
    c                 C   s   t t | _d S r4   )strosgetpidworker_namer:   r0   r0   r1   r8      s   zDBTaskRunner.__init__Nr   Fc                 C   s   t j||||||||	|
||}|tjkrL|j}t }t j|}|j	|d}|r0|j	|d}|tj
krA|j||d}|r@dS n|tjkrL| rLdS |  tjj| j|d |S )z+Simply create a task object in the database)	task_hashr   )r]   r^   Nr   )r   r   Znew_taskrV   rh   rs   r	   rg   unlockedr    rl   updaterm   countsaver   Ztask_createdr   r!   )r7   r   r   r   r]   r^   r_   r   verbose_namecreatorrepeatrepeat_untilrO   r   rs   rg   rt   existingupdatedr0   r0   r1   rP      s,   


zDBTaskRunner.schedulec                    sl   z& fddt j|D d d }|D ]}|| j}|r#|  W S qW d S  ty5   td Y d S w )Nc                    s   g | ]
}|j  jv r|qS r0   )r   rE   ).0r   tasksr0   r1   
<listcomp>   s    z0DBTaskRunner.get_task_to_run.<locals>.<listcomp>   z0Failed to retrieve tasks. Database unreachable.
)r   r   Zfind_availablelockrr   r   r$   warning)r7   r   r   Zavailable_tasksr   Zlocked_taskr0   r   r1   get_task_to_run   s   
zDBTaskRunner.get_task_to_runc                 C   s   t d| || d S )Nz
Running %s)r$   r%   rT   )r7   r   r   r0   r0   r1   rT     s   zDBTaskRunner.run_taskc                 C   s$   |  ||}|r| || dS dS )NTF)r   rT   )r7   r   r   r   r0   r0   r1   rU     s
   zDBTaskRunner.run_next_taskr4   )r?   r@   rA   __doc__r8   rV   rh   rP   r   rT   rU   r0   r0   r0   r1   rF      s    

rF   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )rH   c                 C   s4   || _ | | _| _|| _t|| _|| _|| _d S r4   )	r   rg   r   runnerrV   rc   rP   r   rO   )r7   r   r   rP   r   rO   r   r0   r0   r1   r8     s   
zTaskProxy.__init__c                 O   s   | dd }t|| j}|j}| d|j}|j}| d| j}| dd }| dd }	| dd }
| dd }| d| j	}| j
| j||||||||	|
||S )	NrP   r^   r   rx   ry   rz   r{   rO   )poprV   rc   re   rP   r]   r^   r_   r   rO   r   r   )r7   r   r   rP   r]   r^   r_   r   rx   ry   rz   r{   rO   r0   r0   r1   rC     s    zTaskProxy.__call__c                 C   s
   d| j  S )NzTaskProxy(%s))r   r:   r0   r0   r1   __str__+  s   
zTaskProxy.__str__N)r?   r@   rA   r8   rC   r   r0   r0   r0   r1   rH     s    	rH   c               
   C   s   ddl } ddlm} t D ]/}zt|jj}W n tt	fy#   Y qw z| 
d| W n	 t	y5   Y qw td|j  qdS )zG
    Autodiscover tasks.py files in much the same way as admin app
    r   N)settingsr   z%s.tasks)impZdjango.confr   r   Zget_app_configsr   r   __path__AttributeErrorImportErrorfind_module)r   r   Z
app_configZapp_pathr0   r0   r1   autodiscover1  s   r   r4   )'
__future__r   r   r   	importlibr   Zmultiprocessing.poolr   loggingrp   r'   Zdjango.appsr   Zdjango.db.utilsr   Zdjango.utilsr	   sixr
   Zbackground_task.exceptionsr   Zbackground_task.modelsr   Zbackground_task.settingsr   Zbackground_taskr   	getLoggerr?   r$   r2   r3   objectrD   rV   rF   rH   r   r   r0   r0   r0   r1   <module>   s2   

)9C>