o
    )                     @   s&  d Z ddlmZ ddlmZ ddlm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Zd
ZG dd de
jZG dd de
jZG dd de
jZG dd deejeZG dd deZG dd deZ										d"ddZ							d#ddZd d! ZdS )$z-Utilities to support long running operations.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)progress_tracker)retryzThe operations may still be underway remotely and may still succeed; use gcloud list and describe commands or https://console.developers.google.com/ to check resource state.c                   @      e Zd ZdS )TimeoutErrorN__name__
__module____qualname__ r   r   ?/tmp/google-cloud-sdk/lib/googlecloudsdk/api_lib/util/waiter.pyr
   &       r
   c                   @   r	   )AbortWaitErrorNr   r   r   r   r   r   *   r   r   c                   @   r	   )OperationErrorNr   r   r   r   r   r   .   r   r   c                   @   s:   e Zd ZdZejdd Zejdd Zejdd ZdS )	OperationPollera  Interface for defining operation which can be polled and waited on.

  This construct manages operation_ref, operation and result abstract objects.
  Operation_ref is an identifier for operation which is a proxy for result
  object. OperationPoller has three responsibilities:
    1. Given operation object determine if it is done.
    2. Given operation_ref fetch operation object
    3. Given operation object fetch result object
  c                 C      dS )zGiven result of Poll determines if result is done.

    Args:
      operation: object representing operation returned by Poll method.

    Returns:

    Tr   self	operationr   r   r   IsDone=      
zOperationPoller.IsDonec                 C   r   )zRetrieves operation given its reference.

    Args:
      operation_ref: str, some id for operation.

    Returns:
      object which represents operation.
    Nr   )r   operation_refr   r   r   PollI   r   zOperationPoller.Pollc                 C   r   )zGiven operation message retrieves result it represents.

    Args:
      operation: object, representing operation returned by Poll method.
    Returns:
      some object created by given operation.
    Nr   r   r   r   r   	GetResultU   s   	zOperationPoller.GetResultN)	r   r   r   __doc__abcabstractmethodr   r   r   r   r   r   r   r   2   s    


r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )CloudOperationPollerzlManages a longrunning Operations.

  See https://cloud.google.com/speech/reference/rpc/google.longrunning
  c                 C   s   || _ || _dS )a  Sets up poller for cloud operations.

    Args:
      result_service: apitools.base.py.base_api.BaseApiService, api service for
        retrieving created result of initiated operation.
      operation_service: apitools.base.py.base_api.BaseApiService, api service
        for retrieving information about ongoing operation.

      Note that result_service and operation_service Get request must have
      single attribute called 'name'.
    N)result_serviceoperation_service)r   r"   r#   r   r   r   __init__g   s   
zCloudOperationPoller.__init__c                 C       |j r|jrt|jjdS dS z
Overrides.TFdoneerrorr   messager   r   r   r   r   v   
   zCloudOperationPoller.IsDonec                 C   s"   | j d}| j || dS zOverrides.

    Args:
      operation_ref: googlecloudsdk.core.resources.Resource.

    Returns:
      fetched operation message.
    Getname)r#   GetRequestTyper-   RelativeNamer   r   request_typer   r   r   r   ~   s   	zCloudOperationPoller.Pollc                 C   s.   | j d}t|j}| j ||d dS )zOverrides.

    Args:
      operation: api_name_messages.Operation.

    Returns:
      result of result_service.Get request.
    r-   r/   r.   )r"   r0   r   MessageToPyValueresponser-   )r   r   r3   response_dictr   r   r   r      s   	zCloudOperationPoller.GetResultNr   r   r   r   r$   r   r   r   r   r   r   r   r!   a   s    r!   c                   @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )CloudOperationPollerNoResourceszManages longrunning Operations for Cloud API that creates no resources.

  See https://cloud.google.com/speech/reference/rpc/google.longrunning
  Nc                 C   s   || _ |pdd | _dS )a3  Sets up poller for cloud operations.

    Args:
      operation_service: apitools.base.py.base_api.BaseApiService, api service
        for retrieving information about ongoing operation.

        Note that the operation_service Get request must have a
        single attribute called 'name'.
      get_name_func: the function to use to get the name from the operation_ref.
        This is to allow polling with non-traditional operation resource names.
        If the resource name is compatible with gcloud parsing, use
        `lambda x: x.RelativeName()`.
    c                 S   s   |   S N)r1   )xr   r   r   <lambda>   s    z:CloudOperationPollerNoResources.__init__.<locals>.<lambda>N)r#   get_name)r   r#   get_name_funcr   r   r   r$      s   z(CloudOperationPollerNoResources.__init__c                 C   r%   r&   r'   r   r   r   r   r      r+   z&CloudOperationPollerNoResources.IsDonec                 C   s$   | j d}| j || |dS r,   )r#   r0   r-   r<   r2   r   r   r   r      s   	z$CloudOperationPollerNoResources.Pollc                 C   s   |j S )zOverrides to get the response from the completed operation.

    Args:
      operation: api_name_messages.Operation.

    Returns:
      the 'response' field of the Operation.
    )r5   r   r   r   r   r      s   	z)CloudOperationPollerNoResources.GetResultr9   r7   r   r   r   r   r8      s    
r8     @w ffffff?    c                    s   d |}z6|stj||dn|! |rt|  fdd}t| |||||	|
||	}W d   n1 s5w   Y  W n/ tjyN   td ||d t tj	yj } ztd ||j
jd |j
jtd}~ww | |S )	aA  Waits for poller.Poll and displays pending operation spinner.

  Args:
    poller: OperationPoller, poller to use during retrials.
    operation_ref: object, passed to operation poller poll method.
    message: str, string to display for default progress_tracker.
    custom_tracker: ProgressTracker, progress_tracker to use for display.
    tracker_update_func: func(tracker, result, status), tracker update function.
    pre_start_sleep_ms: int, Time to wait before making first poll request.
    max_retrials: int, max number of retrials before raising RetryException.
    max_wait_ms: int, number of ms to wait before raising WaitException.
    exponential_sleep_multiplier: float, factor to use on subsequent retries.
    jitter_ms: int, random (up to the value) additional sleep between retries.
    wait_ceiling_ms: int, Maximum wait between retries.
    sleep_ms: int or iterable: for how long to wait between trials.

  Returns:
    poller.GetResult(operation).

  Raises:
    AbortWaitError: if ctrl-c was pressed.
    TimeoutError: if retryer has finished without being done.
  z!Aborting wait for operation {0}.
)aborted_messagec                    s    r
 | | d S     d S r9   )Tick)resultstatustrackertracker_update_funcr   r   _StatusUpdate   s   zWaitFor.<locals>._StatusUpdateNz2Operation {0} has not finished in {1} seconds. {2}r>   zIOperation {0} has not finished in {1} seconds after max {2} retrials. {3})formatr   ProgressTracker_SleepMsPollUntilDoner   WaitExceptionr
   _TIMEOUT_MESSAGEMaxRetrialsExceptionstatetime_passed_msretrialr   )pollerr   r*   custom_trackerrI   pre_start_sleep_msmax_retrialsmax_wait_msexponential_sleep_multiplier	jitter_mswait_ceiling_mssleep_msrC   rJ   r   er   rG   r   WaitFor   sH   
#

	r_   c	                    s<   t j||||||d}	 fdd}
|	j j|f|
|d}|S )a  Waits for poller.Poll to complete.

  Note that this *does not* print nice messages to stderr for the user; most
  callers should use WaitFor instead for the best UX unless there's a good
  reason not to print.

  Args:
    poller: OperationPoller, poller to use during retrials.
    operation_ref: object, passed to operation poller poll method.
    max_retrials: int, max number of retrials before raising RetryException.
    max_wait_ms: int, number of ms to wait before raising WaitException.
    exponential_sleep_multiplier: float, factor to use on subsequent retries.
    jitter_ms: int, random (up to the value) additional sleep between retries.
    wait_ceiling_ms: int, Maximum wait between retries.
    sleep_ms: int or iterable: for how long to wait between trials.
    status_update: func(result, state) called right after each trial.

  Returns:
    The return value from poller.Poll.
  )rX   rY   rZ   r[   r\   status_update_funcc                    s     |  S r9   )r   )r   unused_staterU   r   r   
_IsNotDone?  s   z!PollUntilDone.<locals>._IsNotDone)funcargsshould_retry_ifr]   )r   RetryerRetryOnResultr   )rU   r   rX   rY   rZ   r[   r\   r]   status_updateretryerrc   r   r   rb   r   rN     s    rN   c                 C   s   t | d  d S )Nr>   )timesleep)milisecondsr   r   r   rM   K  s   rM   )
NNNr>   Nr?   r@   r>   rA   rB   )Nr?   r@   r>   rA   rB   N)r   
__future__r   r   r   r   rk   apitools.base.pyr   googlecloudsdk.corer   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   sixrP   Errorr
   r   r   with_metaclassABCMetaobjectr   r!   r8   r_   rN   rM   r   r   r   r   <module>   sN   /8<
H
1