Fixed websocket related tasks in InvokeAzContainerInstanceCommand_ExecuteExpanded.cs#22515
Conversation
…nd_ExecuteExpanded.cs
️✔️Az.Accounts
|
| Type | Cmdlet | Description | Remediation |
|---|---|---|---|
| Get-AzContainerGroup | Get-AzContainerGroup Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerGroup | Get-AzContainerGroup changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| Get-AzContainerInstanceCachedImage | Get-AzContainerInstanceCachedImage Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerInstanceCachedImage | Get-AzContainerInstanceCachedImage changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| Get-AzContainerInstanceCapability | Get-AzContainerInstanceCapability Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerInstanceCapability | Get-AzContainerInstanceCapability changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| Get-AzContainerInstanceContainerGroupOutboundNetworkDependencyEndpoint | Get-AzContainerInstanceContainerGroupOutboundNetworkDependencyEndpoint Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerInstanceContainerGroupOutboundNetworkDependencyEndpoint | Get-AzContainerInstanceContainerGroupOutboundNetworkDependencyEndpoint changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| Get-AzContainerInstanceLog | Get-AzContainerInstanceLog Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerInstanceLog | Get-AzContainerInstanceLog changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| Get-AzContainerInstanceUsage | Get-AzContainerInstanceUsage Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| Get-AzContainerInstanceUsage | Get-AzContainerInstanceUsage changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerGroupImageRegistryCredentialObject | New-AzContainerGroupImageRegistryCredentialObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerGroupImageRegistryCredentialObject | New-AzContainerGroupImageRegistryCredentialObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerGroupPortObject | New-AzContainerGroupPortObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerGroupPortObject | New-AzContainerGroupPortObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerGroupVolumeObject | New-AzContainerGroupVolumeObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerGroupVolumeObject | New-AzContainerGroupVolumeObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstanceEnvironmentVariableObject | New-AzContainerInstanceEnvironmentVariableObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstanceEnvironmentVariableObject | New-AzContainerInstanceEnvironmentVariableObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstanceHttpHeaderObject | New-AzContainerInstanceHttpHeaderObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstanceHttpHeaderObject | New-AzContainerInstanceHttpHeaderObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstanceInitDefinitionObject | New-AzContainerInstanceInitDefinitionObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstanceInitDefinitionObject | New-AzContainerInstanceInitDefinitionObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstanceObject | New-AzContainerInstanceObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstanceObject | New-AzContainerInstanceObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstancePortObject | New-AzContainerInstancePortObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstancePortObject | New-AzContainerInstancePortObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. | |
| New-AzContainerInstanceVolumeMountObject | New-AzContainerInstanceVolumeMountObject Changes the ConfirmImpact but does not set the SupportsShouldProcess property to true in the cmdlet attribute. | Determine if the cmdlet should implement ShouldProcess and if so determine if it should implement Force / ShouldContinue | |
| New-AzContainerInstanceVolumeMountObject | New-AzContainerInstanceVolumeMountObject changes the confirm impact. Please ensure that the change in ConfirmImpact is justified | Verify that ConfirmImpact is changed appropriately by the cmdlet. It is very rare for a cmdlet to change the ConfirmImpact. |
️✔️Help File Existence Check
️✔️PowerShell Core - Windows
⚠️ File Change Check
⚠️ PowerShell Core - Windows
Type Cmdlet Description Remediation ⚠️ It is required to update ChangeLog.md if you want to release a new version for Az.ContainerInstance. Add a changelog record under Upcoming Release section with past tense.
️✔️UX Metadata Check
️✔️PowerShell Core - Windows
️✔️Test
️✔️PowerShell Core - Linux
️✔️PowerShell Core - MacOS
️✔️PowerShell Core - Windows
|
Thank you for your contribution andreygoran! We will review the pull request and get back to you soon. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
| private Task PullResponse() | ||
| { | ||
| return Task.Factory.StartNew(async () => | ||
| return Task.Run(async () => |
There was a problem hiding this comment.
https://code-maze.com/csharp-task-run-vs-task-factory-startnew/
Task.Factory.StartNew() vs Task.Run()
- TaskCreationOptions.AttachedToParent vs TaskCreationOptions.DenyChildAttach? TaskCreationOptions.AttachedToParent as WriteObject() in PullResponse() depends on parent task.
- Current vs Default TaskScheduler? Default TaskScheduler. No sure is current TaskScheduler same with default scheduler in ARM deployment environment?
- Task<Task<void>> vs Task<void>? No difference in this case due to no return.
- Object State? No difference in this case as no shared variable is scoped outside of the task block except socket.
There was a problem hiding this comment.
Maybe should use Task.Factory.StartNew/Task.Run(action, this._cancellationTokenSource.Token, TaskCreationOptions.None, TaskScheduler.Default);? @andreygoran what's your thought?
There was a problem hiding this comment.
Task<Task<void>>vsTask<void>I think it's actually crucial in this case. We useTask.WaitAlllater in code https://github.com/Azure/azure-powershell/blob/d6e1dc5e5759ae025a6509886ac5d7580113f5a6/src/ContainerInstance/custom/InvokeAzContainerInstanceCommand_ExecuteExpanded.cs#L45C13-L45C25 andTask<Task<void>>means that the waiting is over when the innerTaskis returned, but this does not mean that the innerTaskis actually completed by that time. HoweverTask.Rundoes understand the semantics ofTask<Task<void>>and actually waits until the inner task is completed.
Another solution would be to use.Unwrap()instead of switchingTask.Factory.StartNewtoTask.Run:
return Task.Factory.StartNew(async () =>
{
...
}, this._cancellationTokenSource.Token).Unwrap();
Maybe should use
Task.Factory.StartNew/Task.Run(action, this._cancellationTokenSource.Token, TaskCreationOptions.None, TaskScheduler.Default);?
I randomly checked a few usages of Task.Run in the project, and I do not see any additional parameters used anywhere. So probably it's fine the way it is.
There was a problem hiding this comment.
Thanks for your opinions.
I prefer
return Task.Factory.StartNew(async () =>
{
...
}, this._cancellationTokenSource.Token).Unwrap();
Because we need TaskCreationOptions.AttachedToParent but Task.Run() uses TaskCreationOptions.DenyChildAttach
There was a problem hiding this comment.
@BethanyZhou I added new commit that restores Task.Factory.StartNew and adds Unwrap()
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
…ecuteExpanded.cs and added .Unwrap()
|
/azp run azure-powershell - powershell-core |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Description
This PR fixes the problem with Invoke-AzContainerInstanceCommand not returning any result when it's run under certain conditions, and closes #22453
The problem occurres when powershell is launched with redirection of input stream (and apparently this is how it's being run in Azure ARM Powershell Deployment Scripts and in Azure Powershell Functions).
Test.ps1code used to reproduce the problem:Results before the fix:
Results after the fix:
Related Issues
Fixed: #22453
Probably related: #19247
Probably related: #15754 (comment)
Root Cause Analysis
The root cause of the bug was using a
return Task.Factory.StartNew(async () => {...})construction to handle working with websockets doing actual communication with container instance. This code pattern is dangerous and should not be used, see for details https://blog.stephencleary.com/2013/08/startnew-is-dangerous.htmlAnother problem was using
Console.KeyAvailablewhich throws an exception when input redirection is used. This was fixed by addingConsole.IsInputRedirectedvalidation.Checklist
CONTRIBUTING.mdand reviewed the following information:generationbranch.ChangeLog.mdfile(s) appropriatelyChangeLog.mdfile can be found atsrc/{{SERVICE}}/{{SERVICE}}/ChangeLog.md## Upcoming Releaseheader in the past tense. Add changelog in description section if PR goes intogenerationbranch.ChangeLog.mdif no new release is required, such as fixing test case only.