-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Service fabric deploy] Re-tries for copy and register commands #7555
Conversation
@@ -43,7 +46,14 @@ function Invoke-ActionWithRetries | |||
{ | |||
if (($null -eq $RetryableExceptions) -or (Test-RetryableException -Exception $_.Exception -AllowedExceptions $RetryableExceptions)) | |||
{ | |||
$shouldRetry = $OnException.Invoke($_.Exception) | |||
if (!$shouldRetry) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets add a verbose statement indicating retry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or a telemetry!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a log statement indicating retry at line no 81
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add telemetry seprately, once I am done with all command re-tries
$RetryMessage, | ||
|
||
[scriptblock] | ||
$OnException = { $true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming like ShouldRetryHandler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to ShouldRetryOnException
-RetryMessage (Get-VstsLocString -Key SFSDK_RetryingGetApplicationType) | ||
} | ||
|
||
function Invoke-CommandWithRetries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invoke-CommandWithDefaultRetries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#fixed
) | ||
|
||
$global:operationId = $SF_Operations.GetApplicationUpgradeStatus | ||
return Get-ServiceFabricApplicationUpgrade -ApplicationName $ApplicationName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No retry here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function has not changed. Github is not showing diff properly.
} | ||
|
||
# if provisioning failed, throw and don't retry | ||
throw (Get-VstsLocString -Key SFSDK_RegisterAppTypeFailedWithStatus -ArgumentList @($appType.Status, $appType.StatusDetails)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to log this and return false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OnException has three possible outcomes:
- true - in this case retry is attempted
- false - in this case it comes out of retry, but without failure. e.g. if get-applicationtype returns that application type is provisioned, we should come out of register-applicationtype retry loop
- throw - it comes out of retry with failure .e.g if get-applicationtype returns that application provisioning failed
$appTypeStatusValidator = { | ||
param($appType) | ||
# if app type does not exist (i.e it got unprovisioned) or if its status has changed to a terminal one, stop wait | ||
if ((!$appType) -or (($appType.Status -ne [System.Fabric.Query.ApplicationTypeStatus]::Provisioning) -and ($appType.Status -ne [System.Fabric.Query.ApplicationTypeStatus]::Unprovisioning))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this statement doesn't look correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is correct. if app type is in terminal state, then retry should not be attempted. This is ActionSuccessValidator delegate and hence $true means no further retry.
$RetryMessage, | ||
|
||
[scriptblock] | ||
$ShouldRetryOnException = { $true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming the success handler to ShouldRetryOnSuccess or ShouldRetry
@@ -43,15 +48,22 @@ function Invoke-ActionWithRetries | |||
{ | |||
if (($null -eq $RetryableExceptions) -or (Test-RetryableException -Exception $_.Exception -AllowedExceptions $RetryableExceptions)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets update the parameter name for Test-RetryableException cmdlet from AllowedExceptions to RetryableExceptions
@@ -328,8 +328,7 @@ | |||
} | |||
|
|||
Write-Host (Get-VstsLocString -Key SFSDK_RegisterAppType) | |||
$global:operationId = $SF_Operations.RegisterApplicationType | |||
Register-ServiceFabricApplicationType @registerParameters | |||
Register-ServiceFabricApplicationTypeAction -RegisterParameters $registerParameters -ApplicationTypeName $names.ApplicationTypeName -ApplicationTypeVersion $names.ApplicationTypeVersion | |||
if (!$?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this since Register-ServiceFabricApplicationTypeAction will never Fail.
This check is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
$global:operationId = $SF_Operations.CopyApplicationPackage | ||
Copy-ServiceFabricApplicationPackage @copyParameters | ||
|
||
Copy-ServiceFabricApplicationPackageAction -CopyParameters $copyParameters | ||
if (!$?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure whether it is necessary or not. Since it existed before my change, I am not going to remove this. May be it is there as Copy command throws a non-terminating error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please go through this article https://blogs.technet.microsoft.com/heyscriptingguy/2011/05/12/powershell-error-handling-and-why-you-should-care/
We've used it because earlier we were directly calling SDK cmdlets (like Copy-ServiceFabricApplicationPackage) so there was some scope of call failures but now we're calling our own utility functions (like Copy-ServiceFabricApplicationPackageAction in this case) so there is no chance for call failure.
My suggestion is to remove this check from here and move it to Copy-ServiceFabricApplicationPackageAction function right after where you're calling Copy-ServiceFabricApplicationPackage cmdlet.
Do the same for all such checks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would make sense to move them to action itself
@@ -328,8 +328,7 @@ | |||
} | |||
|
|||
Write-Host (Get-VstsLocString -Key SFSDK_RegisterAppType) | |||
$global:operationId = $SF_Operations.RegisterApplicationType | |||
Register-ServiceFabricApplicationType @registerParameters | |||
Register-ServiceFabricApplicationTypeAction -RegisterParameters $registerParameters -ApplicationTypeName $names.ApplicationTypeName -ApplicationTypeVersion $names.ApplicationTypeVersion | |||
if (!$?) | |||
{ | |||
throw (Get-VstsLocString -Key SFSDK_RegisterAppTypeFailed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you remove if(!$?) check then please do delete SFSDK_RegisterAppTypeFailed as well in case if its not being used anywhere else.
[scriptblock] | ||
$ActionSuccessValidator = { $true }, | ||
$ResultRetryEvaluator = { $false }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActionRetryEvaluator will be better name for this parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both ResultRetryEvaluator and ExceptionRetryEvaluator will evaluate whether to re-try action or not - one evaluates if action has successfully completed and other will evaluate if action has thrown exception.
Naming just one as ActionRetryEvaluator will be mis-leading.
} | ||
else | ||
{ | ||
throw | ||
} | ||
} | ||
|
||
if (!$exception -and (!$result -or $ActionSuccessValidator.Invoke($result))) | ||
if (!$exception -and (!$result -or !$ResultRetryEvaluator.Invoke($result))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think it should be
if (!$exception -and ($result -and !$ResultRetryEvaluator.Invoke($result)))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$result can be $null if action return void. In such case, we should not retry. Only if $result is non-null, we should evaluate whether to retry or not
$parameters = @{ | ||
Action = $Action | ||
MaxTries = 3; | ||
RetryIntervalInSeconds = 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason for fixing RetryIntervalInSeconds as 10. This is huge. Why not 5 or 3?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any data to have a specific number. This is just a guess as we want to give enough time for any network glitch
@@ -373,9 +371,9 @@ function Publish-UpgradedServiceFabricApplication | |||
|
|||
Write-Host (Get-VstsLocString -Key SFSDK_WaitingForUpgrade) | |||
$upgradeStatusFetcher = { Get-ServiceFabricApplicationUpgradeAction -ApplicationName $ApplicationName } | |||
$upgradeStatusValidator = { param($upgradeStatus) return ($upgradeStatus.UpgradeState -eq "RollingBackCompleted" -or $upgradeStatus.UpgradeState -eq "RollingForwardCompleted") } | |||
$upgradeRetryEvaluator = { param($upgradeStatus) return ($upgradeStatus.UpgradeState -ne "RollingBackCompleted" -and $upgradeStatus.UpgradeState -ne "RollingForwardCompleted") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this logic in Get-ServiceFabricApplicationUpgradeAction similar to what you've done for other cmdlets like Copy and Register.
Currently it is inconsistent!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is consistent. In upgradeRetryEvaluator we are checking the result to decide whether to retry. In case of Register, we need to call Get-ServiceFabricApplicationType only in case of exception and hence that is handled in $exceptionRetryEvaluator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to point out the logic of calling Invoke-ActionWithRetries in this file.
This call should ideally be done in Get-ServiceFabricApplicationUpgradeAction to as we've done for all other cmdlets.
I've raised a quick draft PR #7593 for the same, let me know if this seems fine to you so that I can go ahead test out the change and merge
} | ||
|
||
function Get-ServiceFabricApplicationUpgradeAction | ||
function Wait-ServiceFabricApplicationTypeStatusChange |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function name is very generic however you're checking only for status Provisioning and Unprovisioning.
Consider changing function name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do in next PR
|
||
$exceptionRetryEvaluator = { | ||
param($ex) | ||
$appType = Get-ServiceFabricApplicationTypeAction -ApplicationTypeName $ApplicationTypeName -ApplicationTypeVersion $ApplicationTypeVersion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Incorrect. You might enter into infinite loop. There will be no bound of MaxRetries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get-ServiceFabricApplicationTypeAction has a max tries of 3. Or are you pointing to something different? Can you explain how it will go into infinit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops my mistake. I thought function name is also Register-ServiceFabricApplicationTypeAction.
This is correct!
@@ -43,15 +48,22 @@ function Invoke-ActionWithRetries | |||
{ | |||
if (($null -eq $RetryableExceptions) -or (Test-RetryableException -Exception $_.Exception -AllowedExceptions $RetryableExceptions)) | |||
{ | |||
$shouldRetry = $ExceptionRetryEvaluator.Invoke($_.Exception) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to pass the parameter $_.Exception since you're not using it anywhere for any ExceptionRetryEvaluator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using it in next PR.
No description provided.