
    t                         S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSKJ	r	  SSK
Jr  SS	K
Jr  \R                  r " S
 S\5      r " S S\R"                  5      rg)zIThreading code for estimating total work of long-running gsutil commands.    )absolute_import)print_function)division)unicode_literalsN)thread_message)	constants)parallelism_framework_utilc                   "    \ rS rSrSrSS jrSrg)SeekAheadResult    zResult class for seek_ahead_iterator results.

A class is used instead of a namedtuple, making it easier to document
and use default keyword arguments.
c                     Xl         X l        g)a  Create a SeekAheadResult.

Args:
  est_num_ops: Number of operations the iterated result represents.
      Operation is loosely defined as a single API call for a single
      object. The total number of API calls may not be known at the time of
      iteration, so this number is approximate.
  data_bytes: Number of data bytes that will be transferred (uploaded,
      downloaded, or rewritten) for this iterated result.
N)est_num_ops
data_bytes)selfr   r   s      *platform/gsutil/gslib/seek_ahead_thread.py__init__SeekAheadResult.__init__'   s     # O    )r   r   N)   r   )__name__
__module____qualname____firstlineno____doc__r   __static_attributes__ r   r   r   r       s    !r   r   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )SeekAheadThread6   a  Thread to estimate total work to be performed by all processes and threads.

Because the ProducerThread can only buffer a certain number of tasks on the
global task queue, it cannot reliably provide the total count or size of
iterated results for operations involving many iterated arguments until it
nears the end of iteration.

This thread consumes an iterator that should be functionally identical
to the ProducerThread, but iterates to the end without adding tasks to the
global task queue in an effort to estimate the amount of total work that the
call to Apply will perform. It should be used only for large operations, and
thus it is created by the main ProducerThread only when the number of
iterated arguments exceeds a threshold.

This thread may produce an inaccurate estimate if its iterator produces
different results than the iterator used by the ProducerThread. This can
happen due to eventual listing consistency or due to the source being
modified as iteration occurs.

This thread estimates operations for top-level objects only;
sub-operations (such as a parallel composite upload) should be reported via
the iterator as a single object including the total number of bytes affected.
c                 |   > [         [        U ]  5         X0l        Xl        X l        SU l        U R                  5         g)a]  Initializes the seek ahead thread.

Args:
  seek_ahead_iterator: Iterator matching the ProducerThread's args_iterator,
      but returning only object name and/or size in the result.
  cancel_event: threading.Event for signaling the
      seek-ahead iterator to terminate.
  status_queue: Status queue for posting summary of fully iterated results.
FN)superr   r   status_queueseek_ahead_iteratorcancel_event	terminatestart)r   r#   r$   r"   	__class__s       r   r   SeekAheadThread.__init__O   s4     
/4)+$2$DNJJLr   c           	         SnSn U R                    Hj  nU R                  (       a    g U[        R                  -  S:X  a!  U R                  R                  5       (       a    g XR                  -  nX#R                  -  nMl     U R                  R                  5       (       a  g [        U R                  [        R                  " X[        R                  " 5       5      5        g ! [         a
  n S nAg S nAff = f)Nr   )r#   r%   r   NUM_OBJECTS_PER_LIST_PAGEr$   isSetr   r   OSError_PutToQueueWithTimeoutr"   r   SeekAheadMessagetime)r   num_objectsnum_data_bytesseek_ahead_resultes        r   runSeekAheadThread.runb   s    KN#77
>>
 )===!C$$&&444666  8(   ''(,			56   s   !C 7C   C 
C3.C3)r$   r#   r"   r%   )	r   r   r   r   r   r   r4   r   __classcell__)r'   s   @r   r   r   6   s    0&6 6r   r   )r   
__future__r   r   r   r   	threadingr/   gslibr   gslib.utilsr   r	   PutToQueueWithTimeoutr-   objectr   Threadr   r   r   r   <module>r>      sR    P & %  '     ! 23II !f !,J6i&& J6r   