File: //usr/lib/python3/dist-packages/duplicity/__pycache__/asyncscheduler.cpython-310.pyc
o
�~�_;* � @ s� d Z ddlmZ e�� ddlmZ ddlZddlmZ ddlm Z ddlm
Z
ddlmZ dd lmZ ej
�� Zej
�� ZG d
d� de�ZdS )z_
Asynchronous job scheduler, for concurrent execution with minimalistic
dependency guarantees.
� )�standard_library)�objectN)�log)�require_threading)�interruptably_wait)�async_split)� with_lockc @ sP e Zd ZdZdd� Zdd� Zdd� Zdd � Zd
d� Zdd
� Z dd� Z
dd� ZdS )�AsyncSchedulera�
Easy-to-use scheduler of function calls to be executed
concurrently. A very simple dependency mechanism exists in the
form of barriers (see insert_barrier()).
Each instance has a concurrency level associated with it. A
concurrency of 0 implies that all tasks will be executed
synchronously when scheduled. A concurrency of 1 indicates that a
task will be executed asynchronously, but never concurrently with
other tasks. Both 0 and 1 guarantee strict ordering among all
tasks (i.e., they will be executed in the order scheduled).
At concurrency levels above 1, the tasks will end up being
executed in an order undetermined except insofar as is enforced by
calls to insert_barrier().
An AsynchScheduler should be created for any independent process;
the scheduler will assume that if any background job fails (raises
an exception), it makes further work moot.
c C s� t �d| jjtd�| f � |dksJ d| jjf ��d| _d| _|| _d| _d| _ d| _
t�� | _
|dkr@td|f � dS dS )zr
Create an asynchronous scheduler that executes jobs with the
given level of concurrency.
�%s: %szinstantiating at concurrency %dr z!%s concurrency level must be >= 0FNzconcurrency > 0 (%d))r �Info� __class__�__name__�_�_AsyncScheduler__failed�_AsyncScheduler__failed_waiter�_AsyncScheduler__concurrency�_AsyncScheduler__worker_count�_AsyncScheduler__waiter_count�_AsyncScheduler__barrier� threading� Condition�_AsyncScheduler__cvr )�self�concurrency� r �:/usr/lib/python3/dist-packages/duplicity/asyncscheduler.py�__init__@ s ��
�zAsyncScheduler.__init__c sD t �d� jjtd�f � � jdkr � fdd�}t� j|� dS dS )aL
Proclaim that any tasks scheduled prior to the call to this
method MUST be executed prior to any tasks scheduled after the
call to this method.
The intended use case is that if task B depends on A, a
barrier must be inserted in between to guarantee that A
happens before B.
r
zinserting barrierr c s
d� _ d S �NT)r r �r r r �_insert_barrierf s
z6AsyncScheduler.insert_barrier.<locals>._insert_barrierN)r �Debugr r
r r r r )r r r r r �insert_barrierW s
�zAsyncScheduler.insert_barrierc C sn |dusJ �| j dkr!t�d| jjtd�f tjj� | �||�S t�d| jjtd�f tjj � | �
||�S )a�
Schedule the given task (callable, typically function) for
execution. Pass the given parameters to the function when
calling it. Returns a callable which can optionally be used
to wait for the task to complete, either by returning its
return value or by propagating any exception raised by said
task.
This method may block or return immediately, depending on the
configuration and state of the scheduler.
This method may also raise an exception in order to trigger
failures early, if the task (if run synchronously) or a previous
task has already failed.
NOTE: Pay particular attention to the scope in which this is
called. In particular, since it will execute concurrently in
the background, assuming fn is a closure, any variables used
most be properly bound in the closure. This is the reason for
the convenience feature of being able to give parameters to
the call, to avoid having to wrap the call itself in a
function in order to "fixate" variables in, for example, an
enclosing loop.
Nr r
z4running task synchronously (asynchronicity disabled)z*scheduling task for asynchronous execution)r r r r r
r �InfoCode�synchronous_upload_begin�"_AsyncScheduler__run_synchronously�asynchronous_upload_begin�#_AsyncScheduler__run_asynchronously)r �fn�paramsr r r �
schedule_taskk s
����zAsyncScheduler.schedule_taskc s � fdd�}t � j|� dS )aD
Wait for the scheduler to become entirely empty (i.e., all
tasks having run to completion).
IMPORTANT: This is only useful with a single caller scheduling
tasks, such that no call to schedule_task() is currently in
progress or may happen subsequently to the call to wait().
c s t � j� fdd�� d S )Nc s � j dko � jdkS )Nr )r r r r r r �<lambda>� s z4AsyncScheduler.wait.<locals>._wait.<locals>.<lambda>)r r r r r r �_wait� s z"AsyncScheduler.wait.<locals>._waitN)r r )r r+ r r r �wait� s zAsyncScheduler.waitc s8 ||� � � fdd�}t �d| jjtd�f t jj� |S )Nc s � S �Nr r ��retr r �_waiter� s z3AsyncScheduler.__run_synchronously.<locals>._waiterr
ztask completed successfully)r r r r
r r"