Skip to content
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

Merged
merged 3 commits into from
Jun 26, 2018

Conversation

bishal-pdMSFT
Copy link
Contributor

No description provided.

@@ -43,7 +46,14 @@ function Invoke-ActionWithRetries
{
if (($null -eq $RetryableExceptions) -or (Test-RetryableException -Exception $_.Exception -AllowedExceptions $RetryableExceptions))
{
$shouldRetry = $OnException.Invoke($_.Exception)
if (!$shouldRetry)
{
Copy link
Member

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or a telemetry!

Copy link
Contributor Author

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

Copy link
Contributor Author

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 }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider renaming like ShouldRetryHandler

Copy link
Contributor Author

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invoke-CommandWithDefaultRetries

Copy link
Contributor Author

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No retry here?

Copy link
Contributor Author

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))
Copy link
Member

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

Copy link
Contributor Author

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:

  1. true - in this case retry is attempted
  2. 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
  3. 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)))
Copy link
Member

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

Copy link
Contributor Author

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 }
Copy link
Member

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

@bishal-pdMSFT bishal-pdMSFT merged commit 1d75fa8 into master Jun 26, 2018
@@ -43,15 +48,22 @@ function Invoke-ActionWithRetries
{
if (($null -eq $RetryableExceptions) -or (Test-RetryableException -Exception $_.Exception -AllowedExceptions $RetryableExceptions))
Copy link

@kuvinodms kuvinodms Jun 28, 2018

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 (!$?)

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.

Copy link
Contributor Author

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 (!$?)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is unnecessary.

Copy link
Contributor Author

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.

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!

Copy link
Contributor Author

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)

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 },

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

Copy link
Contributor Author

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)))

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)))

Copy link
Contributor Author

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;

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?

Copy link
Contributor Author

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") }

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!

Copy link
Contributor Author

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

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

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.

Copy link
Contributor Author

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
Copy link

@kuvinodms kuvinodms Jun 28, 2018

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.

Copy link
Contributor Author

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?

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)

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

Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants