
    >              
          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JrJ	r	J
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rSr " S S\R,                  5      rS\	\R0                     S\\\4   4S jrS\\\4   S\\\4   S\\\4   4S jrS\\\4   S\\\4   4S jrS\\\4   4S jrS\\\4   S\\\4   4S jrS\R0                  4S jr S r!S r"S \\\4   4S! jr#S\	\R0                     S\\\
\\$4   4   S\	\R0                     4S" jr%S\	\R0                     S#\S\	\R0                     4S$ jr&S% r'S\	\R0                     S\4S& jr( " S' S(\)5      r*S)\*4S* jr+S\	\
\R0                  \RX                  4      S#\S\\\
\R0                  \RX                  4   4   4S+ jr-S,\R\                  S\	\*   4S- jr/g).z0Operations on WorkerPool V2 API instance splits.    )absolute_import)division)print_function)unicode_literalsN)DictListUnion)resource_name_conversion)
exceptions)instance_split)worker_pool-LATESTc                       \ rS rSrSrSrg)&InvalidInstanceSplitSpecificationError)   z:Error to indicate an invalid instance split specification. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       7lib/googlecloudsdk/command_lib/run/v2/instance_split.pyr   r   )   s    Br   r   splitsreturnc                    0 nU  H  nUR                   [        R                  R                  :X  a  UR                  U[
        '   M@  UR                   [        R                  R                  :X  d  Mj  UR                  XR                  '   M     U$ )z:Returns the current instance split percentages into a map.)type_r   InstanceSplitAllocationType%INSTANCE_SPLIT_ALLOCATION_TYPE_LATESTpercentLATEST_REVISION_KEY'INSTANCE_SPLIT_ALLOCATION_TYPE_REVISIONrevision)r   current_splitssplits      r   _GetCurrentSplitsMapr(   /   sv     .e55[[	\ -2MMn()55]]	^ (-}}n^^$  
r   new_percentagesr&   c                 R    0 nUR                  5        H  u  p4X0;  d  M  XBU'   M     U$ )z`Returns the instance splits that are in the current splits but not specified in new_percentages.)items)r)   r&   resulttargetr"   s        r   _GetUnspecifiedSplitsr.   B   s2    
 &'--/of$Vn 0 
-r   
new_splitsunspecified_targetsc                 2   [        U R                  5       5      S:  a  [        S5      eU R                  5        H+  u  p#US:  d  US:  d  M  [        SR	                  X#5      5      e   U(       d)  [        U R                  5       5      S:  a  [        S5      egg)z-Validates the new instance split percentages.d   z5The sum of instance split specifications exceeds 100.r   zAInstance split specification for {} is {}%, not between 0 and 100z[Every target with instance split is updated but 100% of total split has not been specified.N)sumvaluesr   r+   format)r/   r0   r-   r"   s       r   _ValidateNewSplitsr6   N   s     				#
0?  $))+of{gm2
M6&"  , 
Z%6%6%8!9C!?
0	#  "@	r   c                     SnU R                  5        H/  u  p#US:  d  US:  a  [        SR                  X#5      5      eX-  nM1     US:w  a  [        SR                  U5      5      eg)z1Validates the current instance split percentages.r   r2   zFCurrent instance split allocation for {} is {}%, not between 0 and 100z:Current instance split allocation of {} is not 100 percentN)r+   
ValueErrorr5   )r&   total_percentr-   r"   s       r   _ValidateCurrentSplitsr:   e   s|    -'--/of{gm(  M 0 c
DKK	
  r   unspecified_splitsc                     S[        U R                  5       5      -
  nUS:X  a  0 $ [        UR                  5       5      n[        U5      U-  n0 nUR                  5        H  u  pgXt-  XV'   M     U$ )zoModifies the unspecified splits by assigning the remaining split percent proportionally to the original splits.r2   r   )r3   r4   floatr+   )r/   r;   percent_to_assignoriginal_splits_percentreduction_ratiomodified_splitsr-   r"   s           r   _ModifyUnspecifiedSplitsrB   w   s}     C
 1 1 344!I 2 9 9 ;<+,/FF/ /+113of%7O 4	r   r'   c                     U R                   [        R                  R                  :X  a  [        nOU R
                  n[        U5      $ )zSorted key function to order InstanceSplit objects by key.

Args:
  split: A InstanceSplit.

Returns:
  A value that sorts by revisionName with LATEST_REVISION_KEY
  last.
)typer   r    r!   r#   r%   _SortKeyFromKey)r'   keys     r   _SortKeyFromInstanceSplitrG      s;     jj		3	3	Y	YZ C
..C		r   c                 .    U [         :X  a  SU 4nU$ SU 4nU$ )ag  Sorted key function to order InstanceSplit keys.

InstanceSplits keys are one of:
o revisionName
o LATEST_REVISION_KEY

Note LATEST_REVISION_KEY is not a str so its ordering with respect
to revisionName keys is hard to predict.

Args:
  key: Key for a InstanceSplits dictionary.

Returns:
  A value that sorts by revisionName with LATEST_REVISION_KEY
  last.
      )r#   )rF   r,   s     r   rE   rE      s-    " 	XF 
- XF	-r   c                 D    U u  pSU[        U5      -
  -
  U[        U5      /$ )a  Returns object that sorts in the order we correct split rounding errors.

The caller specifies explicit split percentages for some revisions and
this module scales instance split for remaining revisions that are already
serving instance split up or down to assure that 100% of instance split is
assigned.
This scaling can result in non integer percentages that Cloud Run
does not supprt. We correct by:
  - Trimming the decimal part of float_percent, int(float_percent)
  - Adding an extra 1 percent instance split to enough revisions that have
    had their instance split reduced to get us to 100%

The returned value sorts in the order we correct revisions:
  1) Revisions with a bigger loss due are corrected before revisions with
     a smaller loss. Since 0 <= loss < 1 we sort by the value:  1 - loss.
  2) In the case of ties revisions with less instance split are corrected
  before
     revisions with more instance split.
  3) In case of a tie revisions with a smaller key are corrected before
     revisions with a larger key.

Args:
  key_and_percent: tuple with (key, float_percent)

Returns:
  A value that sorts with respect to values returned for
  other revisions in the order we correct for rounding
  errors.
rJ   )intrE   )key_and_percentrF   float_percents      r    _NewRoundingCorrectionPrecedencerO      s3    < '#=3}--.c
 r   float_percentagesc                 @   U  Vs0 s H  o[        X   5      _M     nn[        [        [        U R                  5       5      5      5      [        UR                  5       5      -
  n[	        U R                  5       [        S9nUSU  H  u  pVX%==   S-  ss'   M     U$ s  snf )z$Returns rounded integer percentages.rF   NrJ   )rL   roundr3   r4   sortedr+   rO   )rP   krounded_percentageslosscorrection_precedencerF   _s          r   _IntPercentagesrZ      s     ->,=q!	"",=   
U3(//123	4s  "8 
$ !%E &et,fc! -	s   Bc                    [        U 5      n[        U5        [        X5      n[        X5        [	        X5      nUR                  U5        [        U5      n[        UR                  5        VVs/ s Hk  u  pgUS:  d  M  [        R                  " U[        :X  a  [        R                  R                  O[        R                  R                  U[        :w  a  UOSUS9PMm     snn[        S9$ s  snnf )z$Returns the updated instance splits.r   Nr   r%   r"   rR   )r(   r:   r.   r6   rB   updaterZ   rT   r+   r   InstanceSplitr#   r    r!   r$   rG   )r&   r/   current_splits_mapr;   unspecified_splits_modifiedint_percent_splitsrF   r"   s           r   GetUpdatedSplitsrb      s     ,N;+,,ZLZ4 !9! /0&z2	 1668
 9lcq[.
&
&++ #>>dd!==ee!%88sd 9
 $
 
s   ,C)
<A"C)
latest_ready_revision_namec                    [        U 5      n[        U;   a,  UR                  [        5      nUR                  US5      U-   X!'   [	        UR                  5        VVs/ s Hk  u  pEUS:  d  M  [        R                  " U[        :X  a  [        R                  R                  O[        R                  R                  U[        :w  a  UOSUS9PMm     snn[        S9$ s  snnf )zVReturns the instance splits with LATEST assignment moved to the latest ready revision.r   Nr\   rR   )r(   r#   popgetrT   r+   r   r^   r    r!   r$   rG   )r&   rc   r_   latestrF   r"   s         r   ZeroLatestAssignmentrh     s    
 ,N;..##$78F91=F 2 
 1668
 9lcq[.
&
&++ #>>dd!==ee!%88sd 9
 $
 
s   C
*A"C
c                 ,    U [         :X  a  [         $ U  S3$ )N%)_MISSING_PERCENT)r"   s    r   _FormatPercentagerl   2  s      Ya=r   c                 V    [        U  Vs/ s H  oR                  PM     sn5      $ s  snf )z2Returns the sum of the instance split percentages.)r3   r"   )r   r'   s     r   _SumPercentrn   9  s!    	0mm0	110s   &c                       \ rS rSrSrS\\R                     S\\R                     S\	S\
4S jr\S 5       r\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       rSrg)InstanceSplitPairi>  zHolder for InstanceSplit status information.

The representation of the status of instance split for a worker pool
includes:
  o User requested assignments (instance_splits)
  o Actual assignments (instance_split_statuses)
target_splitsr&   revision_namerg   c                 4    Xl         X l        X0l        X@l        g)a  Creates a new InstanceSplitPair.

Args:
  target_splits: A list of target instance splits that all reference the
    same revision, either by name or the latest ready.
  current_splits: A list of current instance splits that all reference the
    same revision, either by name or the latest ready.
  revision_name: The name of the revision referenced by the instance splits.
  latest: A boolean indicating if these instance splits reference the latest
    ready revision.

Returns:
  A new InstanceSplitPair instance.
N)_target_splits_current_splits_revision_name_latest)selfrq   r&   rr   rg   s        r   __init__InstanceSplitPair.__init__G  s    * ()'Lr   c                 H    U R                   (       a  [        $ U R                  $ )zThe key for the instance split.latest_revisionr#   rr   rx   s    r   rF   InstanceSplitPair.keya  s     #'"6"6ND<N<NNr   c                     U R                   $ )z9True if the instance split reference the latest revision.)rw   r~   s    r   r}   !InstanceSplitPair.latest_revisionf  s     <<r   c                     U R                   $ )z6Name of the revision referenced by the instance split.)rv   r~   s    r   rr   InstanceSplitPair.revision_namek  s     r   c                     U R                   (       a)  [        R                  " [        U R                   5      5      $ [        $ )z;Target percent of instance split allocated to the revision.)rt   six	text_typern   rk   r~   s    r   target_percent InstanceSplitPair.target_percentp  s-     ]];t':':;<<r   c                     U R                   (       a)  [        R                  " [        U R                   5      5      $ [        $ )z<Current percent of instance split allocated to the revision.)ru   r   r   rn   rk   r~   s    r   status_percent InstanceSplitPair.status_percentx  s-     ]];t';';<==r   c                     U R                   U R                  :X  a  [        U R                   5      $ [        U R                  5      S S[        U R                   5       S3$ )z Human readable revision percent.4 (currently ))r   r   rl   r~   s    r   display_percent!InstanceSplitPair.display_percent  s`     d111t2233 t223A6 7 3 345Q8r   c                 h    U R                   (       a  [         SU R                   S3$ U R                  $ )z#Human readable revision identifier.r   r   r|   r~   s    r   display_revision_id%InstanceSplitPair.display_revision_id  s4     #$L1C1C0DAFFr   )ru   rw   rv   rt   N)r   r   r   r   r   r   r   r^   InstanceSplitStatusstrboolry   propertyrF   r}   rr   r   r   r   r   r   r   r   r   rp   rp   >  s    .667 >==> 	
 4 O O              r   rp   pairc                 `    U R                   (       a  [        nOU R                  n[        U5      $ )zSorted key function to order InstanceSplitPair objects by key.

Args:
  pair: A InstanceSplitPair.

Returns:
  A value that sorts by revisionName with LATEST_REVISION_KEY last.
)r}   r#   rr   rE   )r   rF   s     r   _SortKeyFromInstanceSplitPairr     s(     

C


C		r   c                 *   [         R                  " [        5      nU  Hr  nUR                  [        R
                  R                  :X  d  UR                  U:X  a  U[           R                  U5        MU  X#R                     R                  U5        Mt     U$ )a[  Returns the instance split list into a map.

The map uses LATEST_REVISION_KEY as the key for the latest ready revision.

Args:
  splits: A list of InstanceSplit or InstanceSplitStatus objects.
  latest_ready_revision_name: The name of the latest ready revision.

Returns:
  A map of revision names to InstanceSplit or InstanceSplitStatus objects.
)
collectionsdefaultdictlistr   r   r    r!   r%   r#   append)r   rc   
splits_mapr'   s       r   _GetSplitsMapr     sx    & &&t,*e55[[	\>>77$%,,U3 ''.  
r   r   c           
         / n [         R                  " U R                  5      n[	        U R
                  U5      n[	        U R                  U5      n[        U5      R                  U5       HS  nU[        :X  a  UOUnUR                  [        UR                  U5      UR                  U5      UU[        :H  5      5        MU     [        U[        S9$ ! [         a    Sn Nf = f)z5Returns the instance split pairs for the worker pool. rR   )r
   GetNameFromFullChildNamelatest_ready_revisionAttributeErrorr   instance_splitsinstance_split_statusessetunionr#   r   rp   rf   rT   r   )r   instance_split_pairsrc   rq   r&   rF   rr   s          r   GetInstanceSplitPairsr     s     $ 99--	
   !!#=- !))+E. %%n5c&)-@&@"c  c"s#&&		
	 6 
$*G	HH) 
 $!#$s    C CC)0r   
__future__r   r   r   r   r   typingr   r   r	   googlecloudsdk.command_lib.runr
   googlecloudsdk.corer   ;googlecloudsdk.generated_clients.gapic_clients.run_v2.typesr   r   worker_pool_objectsr   rk   r#   Errorr   r^   r   rL   r(   r.   r6   r:   rB   rG   rE   rO   rZ   r=   rb   rh   rl   rn   objectrp   r   r   r   
WorkerPoolr   r   r   r   <module>r      s   7 '  % '  $ $ C * V j 
    Z-=-= --.	#s(^&	#s(^	cN	 
#s(^	S#X59#s(^.4S> $S#X48cN6^%A%A (0#LtCH~   556 S%U
++,  
.
&
&' F556 # 
.
&
&'62^99: 2s 2
S  S l(9  n**N,N,NNO !$	
 
~++^-O-OO	PP@I$//I	
Ir   