From b2be584b89b865a68393f6df0c3beaa1e3290bd5 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Tue, 18 Jun 2019 17:01:09 -0300 Subject: [PATCH 1/9] first draft --- .../RFCNNNN-Improve-Background-Operator.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 1-Draft/RFCNNNN-Improve-Background-Operator.md diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md new file mode 100644 index 00000000..d5286212 --- /dev/null +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -0,0 +1,167 @@ +--- +RFC: RFCnnnn +Author: Kirk Munro +Status: Draft +SupercededBy: +Version: 0.1 +Area: PSEngine,Host,Jobs +Comments Due: July 20, 2019 +Plan to implement: Yes +--- + +# Improved the `&` Background Operator + +This RFC was born from some side comments made on [PowerShell Issue #9873](https://github.com/PowerShell/PowerShell/issues/9873#issuecomment-501289658). + +The `&` background operator has great potential, and it could be encouraging +for users who come to PowerShell from bash since it is already familiar to +them; however, the initial implementation of this operator was simply to +invoke `Start-Job` in a manner familiar with bash users, and the current +implementation doesn't work like the same operator does in bash. It also left +several opportunities for a more feature-rich PowerShell-based version of that +operator on the table. The end result is a feature that feels more like a +checklist item that is partially checked off than a feature that adds +significant, tangible value to the PowerShell community. In a nutshell, we can +and should do better. + +## Motivation + +As a user,
+I can reference the most recent job launched with `Start-Job` or the `&` background operator in a `$!` variable
+So that I can write my handling of those jobs in a consistent way without the job object or id, using the same variable that is used in bash for the same purpose. + +As a user,
+I can see the output of jobs launched with the `&` background operator in my current host by default
+So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. + +As a user,
+I can launch jobs silently with a new `&!` background operator
+So that their output is only available when I use `Receive-Job` to receive that output. + +As a user,
+I can use the `&` operator (and the proposed `&!` operator) after the stop parsing sigil (`--%`)
+So that I can launch legacy commands in the background more easily, without having to use `Start-Job`. + +Also, for completeness/functional parity with cmdlets: + +As a user,
+I can see the output of jobs launched with `Start-Job` in my current host by using a new `-ShowInHost` switch
+So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. + +As a user,
+I can show or hide the output of running jobs by using new `Show-JobData` and `Hide-JobData` cmdlets
+So that I can control the display and monitoring of running jobs without having to muck around with `Receive-Job -Keep`. + +As a PowerShell contributor,
+I can see the process ID associated with any background job by looking at the job members
+So that I can more easily attach the Visual Studio debugger to that job when I need to. + +## User Experience + +### Launching a background job with the output visible in the host + +```powershell +# This command: +Get-Process & +# Would return the same output as this command: +Start-Job {Get-Process} -ShowInHost +``` + +```output +Id Name PSJobTypeName State HasMoreData Location Command +-- ---- ------------- ----- ----------- -------- ------- +1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man… +``` + +In addition to the output above, which is the job object created by the command +that was invoked, PowerShell would show the output from the job (and any other +job) launched this way in an overlay much like the output from Write-Progress, +with the job data from any stream appearing as it is output in the overlay, +prefixed with "[JobName]:" (e.g. [Job1]: ). This overlay would be slightly +larger than Write-Progress so that users could see more output from the job in +the overlay, and when all jobs sharing output complete the overlay would +disappear after a delay (5 seconds). Progress messages from the jobs would +appear above the output. + +### Launching a background job quietly and referencing the job with the `$!` variable + +```powershell +# These commands: +$null = Get-Process &! +$! +# Would return the same output as these commands: +$null = Start-Job {Get-Process} +$! +``` + +```output +Id Name PSJobTypeName State HasMoreData Location Command +-- ---- ------------- ----- ----------- -------- ------- +1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man… +``` + +The `$!` variable in those two commands returns the job that was created with +the command before it. + +The `&!` operator permits launching a job using an operator without any of the +messages from the various streams appearing by default in the console. + +### Launching a legacy command with the stop-parsing sigil and either the `&` or `&!` background operator + +This corrects a limitation with the background operator(s), which currently +treat `&` (and `&!`) as an argument instead when used after the stop-parsing +sigil. + +```powershell +./plink.exe" --% $Hostname -l $Username -pw $Password $Command & +``` + +```output +Id Name PSJobTypeName State HasMoreData Location Command +-- ---- ------------- ----- ----------- -------- ------- +1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man… +``` + +### Showing or hiding the data from one or more jobs + +This allows job data to be shown or hidden on demand for any jobs. + +```powershell +# Show the data from job ids 1-5 +Show-JobData -Id 1..5 +# Hide the data from job name Job2 +Hide-JobData -Name Job2 +# Show the data for the last job we launched +Show-JobData -Job $! +``` + +```output +# As described in the comments above, with the data showing in an overlay +``` + +### Viewing the process ID for a job + +This shows how you can access the read-only process ID for a job. + +```powershell +$!.ProcessId +``` + +```output +# The process id for the background job +``` + +## Specification + +1. For jobs invoked with `&` or `Start-Job -ShowInHost`, or for jobs referenced in `Show-JobData`, hook up event handlers on the data stream collections for the job objects to capture the data from the jobs as it is added in real time, and show that data in the current terminal with the job ID in front of that data. Mirror how `ProgressInformation` is rendered when it comes to showing job data this way. +1. Add a `&!` operator that starts a job with the data display turned off. +1. Add a boolean property to `BackgroundJob` objects called `ShowData` that identifies if the job is currently configured to show data or not. +1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. +1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true and hooks up event handlers as described in the first item in this list. +1. Add a `$!` variable to store the most recently run job. + +## Alternate Proposals and Considerations + +### Add the process ID to the default output for a background job + +It may seem like a good idea to show the process ID for a background job in the default tabular output. While this would be convenient, we also have thread jobs that don't have a process ID, so it is probably better to leave it out for consistency across all jobs. It is always accessible via the `ProcessID` member of background jobs regardless. From 2e2de26e139c040a63d47ac1462b856d158a02f8 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Fri, 21 Jun 2019 10:09:28 -0300 Subject: [PATCH 2/9] update to support multiple jobs in $! --- .../RFCNNNN-Improve-Background-Operator.md | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index d5286212..4040aea6 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -27,7 +27,7 @@ and should do better. ## Motivation As a user,
-I can reference the most recent job launched with `Start-Job` or the `&` background operator in a `$!` variable
+I can reference the most recent job(s) launched with `Start-Job` or the `&` background operator in a `$!` variable
So that I can write my handling of those jobs in a consistent way without the job object or id, using the same variable that is used in bash for the same purpose. As a user,
@@ -106,6 +106,24 @@ the command before it. The `&!` operator permits launching a job using an operator without any of the messages from the various streams appearing by default in the console. +### Fanning out to multiple background jobs and referencing the jobs with the `$!` variable + +```powershell +$null = cmd1 & cmd2 & cmd3 & +$! +``` + +```output +Id Name PSJobTypeName State HasMoreData Location Command +-- ---- ------------- ----- ----------- -------- ------- +1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... +2 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... +3 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... +``` + +The `$!` variable in those two commands returns the jobs that were created with +the command before it. + ### Launching a legacy command with the stop-parsing sigil and either the `&` or `&!` background operator This corrects a limitation with the background operator(s), which currently @@ -119,7 +137,7 @@ sigil. ```output Id Name PSJobTypeName State HasMoreData Location Command -- ---- ------------- ----- ----------- -------- ------- -1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man… +1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... ``` ### Showing or hiding the data from one or more jobs @@ -131,7 +149,7 @@ This allows job data to be shown or hidden on demand for any jobs. Show-JobData -Id 1..5 # Hide the data from job name Job2 Hide-JobData -Name Job2 -# Show the data for the last job we launched +# Show the data for the last job (or jobs) we launched Show-JobData -Job $! ``` @@ -148,7 +166,7 @@ $!.ProcessId ``` ```output -# The process id for the background job +# The process id for the background job(s) ``` ## Specification @@ -158,7 +176,7 @@ $!.ProcessId 1. Add a boolean property to `BackgroundJob` objects called `ShowData` that identifies if the job is currently configured to show data or not. 1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. 1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true and hooks up event handlers as described in the first item in this list. -1. Add a `$!` variable to store the most recently run job. +1. Add a `$!` variable to store the most recently run job (or jobs if multiple jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3`). ## Alternate Proposals and Considerations From 54582fcd1d8b0945e38bbfee46ca4d090d06bd06 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Thu, 27 Jun 2019 14:15:45 -0300 Subject: [PATCH 3/9] add related RFC link; minor update --- 1-Draft/RFCNNNN-Improve-Background-Operator.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index 4040aea6..c06d5305 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -24,6 +24,8 @@ checklist item that is partially checked off than a feature that adds significant, tangible value to the PowerShell community. In a nutshell, we can and should do better. +Note that there is a [related RFC about adding a `~&` ThreadJob operator](https://github.com/PowerShell/PowerShell-RFC/pull/205). + ## Motivation As a user,
@@ -45,7 +47,7 @@ So that I can launch legacy commands in the background more easily, without havi Also, for completeness/functional parity with cmdlets: As a user,
-I can see the output of jobs launched with `Start-Job` in my current host by using a new `-ShowInHost` switch
+I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowInHost` switch
So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. As a user,
From 7f6a073aebdf9ff32d068cb0f6f42a6be61eaecf Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Sat, 29 Jun 2019 13:37:47 -0300 Subject: [PATCH 4/9] add consideration and fix formatting --- .../RFCNNNN-Improve-Background-Operator.md | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index c06d5305..e72b1b42 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -173,15 +173,36 @@ $!.ProcessId ## Specification -1. For jobs invoked with `&` or `Start-Job -ShowInHost`, or for jobs referenced in `Show-JobData`, hook up event handlers on the data stream collections for the job objects to capture the data from the jobs as it is added in real time, and show that data in the current terminal with the job ID in front of that data. Mirror how `ProgressInformation` is rendered when it comes to showing job data this way. +1. For jobs invoked with `&` or `Start-Job -ShowInHost`, or for jobs referenced +in `Show-JobData`, hook up event handlers on the data stream collections for +the job objects to capture the data from the jobs as it is added in real time, +and show that data in the current terminal with the job ID in front of that +data. Mirror how `ProgressInformation` is rendered when it comes to showing job +data this way. 1. Add a `&!` operator that starts a job with the data display turned off. -1. Add a boolean property to `BackgroundJob` objects called `ShowData` that identifies if the job is currently configured to show data or not. -1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. -1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true and hooks up event handlers as described in the first item in this list. -1. Add a `$!` variable to store the most recently run job (or jobs if multiple jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3`). +1. Add a boolean property to `BackgroundJob` objects called `ShowData` that +identifies if the job is currently configured to show data or not. +1. Add an integer property to `BackgroundJob` objects called `ProcessId` that +identifies the ID of the process where the job is running. +1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true +and hooks up event handlers as described in the first item in this list. +1. Add a `$!` variable to store the most recently run job (or jobs if multiple +jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3`). ## Alternate Proposals and Considerations ### Add the process ID to the default output for a background job -It may seem like a good idea to show the process ID for a background job in the default tabular output. While this would be convenient, we also have thread jobs that don't have a process ID, so it is probably better to leave it out for consistency across all jobs. It is always accessible via the `ProcessID` member of background jobs regardless. +It may seem like a good idea to show the process ID for a background job in the +default tabular output. While this would be convenient, we also have thread +jobs that don't have a process ID, so it is probably better to leave it out for +consistency across all jobs. It is always accessible via the `ProcessID` member +of background jobs regardless. + +### Flip the silent/noisy approach with the operators + +Since we've already shipped the `&` background operator, and since it already +runs silent today, leave that as is and make the `&!` background operator run +with output showing in the overlay. While this is not consistent with bash, it +may be less disruptive to folks using `&` already, and still offers options +with and without data showing in an overlay. From 0f8a15384aec71b8dd82dc0c332e9855bf0063a1 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Sun, 30 Jun 2019 14:23:16 -0300 Subject: [PATCH 5/9] flipped approach to preserve current behavior --- .../RFCNNNN-Improve-Background-Operator.md | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index e72b1b42..86c9e192 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -33,12 +33,8 @@ I can reference the most recent job(s) launched with `Start-Job` or the `&` back So that I can write my handling of those jobs in a consistent way without the job object or id, using the same variable that is used in bash for the same purpose. As a user,
-I can see the output of jobs launched with the `&` background operator in my current host by default
-So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. - -As a user,
-I can launch jobs silently with a new `&!` background operator
-So that their output is only available when I use `Receive-Job` to receive that output. +I can launch jobs with a new `&!` background operator that will show job progress in an overlay
+So that watch the concurrent progress of multiple background jobs in my host without blocking my console. As a user,
I can use the `&` operator (and the proposed `&!` operator) after the stop parsing sigil (`--%`)
@@ -58,13 +54,20 @@ As a PowerShell contributor,
I can see the process ID associated with any background job by looking at the job members
So that I can more easily attach the Visual Studio debugger to that job when I need to. +Last, one describing the existing motivation for the `&` background operator +(this is already in place today): + +As a user,
+I can launch jobs silently with the `&` background operator
+So that I can easily run pipelines as jobs in my automation solutions without showing output. + ## User Experience ### Launching a background job with the output visible in the host ```powershell # This command: -Get-Process & +Get-Process &! # Would return the same output as this command: Start-Job {Get-Process} -ShowInHost ``` @@ -89,7 +92,7 @@ appear above the output. ```powershell # These commands: -$null = Get-Process &! +$null = Get-Process & $! # Would return the same output as these commands: $null = Start-Job {Get-Process} @@ -102,11 +105,12 @@ Id Name PSJobTypeName State HasMoreData Location 1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man… ``` -The `$!` variable in those two commands returns the job that was created with -the command before it. +The `&` operator permits launching a job using an operator without any of the +messages from the various streams appearing by default in the console (this is +how this operator works today). -The `&!` operator permits launching a job using an operator without any of the -messages from the various streams appearing by default in the console. +The `$!` variable in the subsequent command returns the job that was created +with the command before it. ### Fanning out to multiple background jobs and referencing the jobs with the `$!` variable @@ -173,13 +177,13 @@ $!.ProcessId ## Specification -1. For jobs invoked with `&` or `Start-Job -ShowInHost`, or for jobs referenced -in `Show-JobData`, hook up event handlers on the data stream collections for -the job objects to capture the data from the jobs as it is added in real time, -and show that data in the current terminal with the job ID in front of that -data. Mirror how `ProgressInformation` is rendered when it comes to showing job -data this way. -1. Add a `&!` operator that starts a job with the data display turned off. +1. For jobs invoked with `&!` or `Start-Job -ShowInHost`, or for jobs +referenced in `Show-JobData`, hook up event handlers on the data stream +collections for the job objects to capture the data from the jobs as it is +added in real time, and show that data in the current terminal with the job ID +in front of that data. Mirror how `ProgressInformation` is rendered when it +comes to showing job data this way. +1. Add a `&!` operator that starts a job with the data display turned on. 1. Add a boolean property to `BackgroundJob` objects called `ShowData` that identifies if the job is currently configured to show data or not. 1. Add an integer property to `BackgroundJob` objects called `ProcessId` that @@ -187,7 +191,7 @@ identifies the ID of the process where the job is running. 1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true and hooks up event handlers as described in the first item in this list. 1. Add a `$!` variable to store the most recently run job (or jobs if multiple -jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3`). +jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3 &`). ## Alternate Proposals and Considerations @@ -201,8 +205,12 @@ of background jobs regardless. ### Flip the silent/noisy approach with the operators -Since we've already shipped the `&` background operator, and since it already -runs silent today, leave that as is and make the `&!` background operator run -with output showing in the overlay. While this is not consistent with bash, it -may be less disruptive to folks using `&` already, and still offers options -with and without data showing in an overlay. +This approach is proposed because we've already shipped the `&` background +operator, with jobs running silent by default. In bash, if you run a command in +the background using the `&` control operator, the output is displayed in the +current terminal. This discrepancy may be confusing to users. If we feel that +the PowerShell `&` background operator should be more consistent with the bash +equivalent, we could make the `&` background operator show output by default +and have the new `&!` background operator run silent. This wouldn't be a +breaking change, but it would change the behavior for any scripts that are +already using the `&` background operator today. From cef2c0523e58b078f65f52a948947b7159760a59 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Sun, 30 Jun 2019 14:27:06 -0300 Subject: [PATCH 6/9] rename ShowInHost as ShowData --- 1-Draft/RFCNNNN-Improve-Background-Operator.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index 86c9e192..059a498e 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -43,7 +43,7 @@ So that I can launch legacy commands in the background more easily, without havi Also, for completeness/functional parity with cmdlets: As a user,
-I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowInHost` switch
+I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowData` switch
So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. As a user,
@@ -69,7 +69,7 @@ So that I can easily run pipelines as jobs in my automation solutions without sh # This command: Get-Process &! # Would return the same output as this command: -Start-Job {Get-Process} -ShowInHost +Start-Job {Get-Process} -ShowData ``` ```output @@ -177,18 +177,18 @@ $!.ProcessId ## Specification -1. For jobs invoked with `&!` or `Start-Job -ShowInHost`, or for jobs -referenced in `Show-JobData`, hook up event handlers on the data stream -collections for the job objects to capture the data from the jobs as it is -added in real time, and show that data in the current terminal with the job ID -in front of that data. Mirror how `ProgressInformation` is rendered when it -comes to showing job data this way. +1. For jobs invoked with `&!` or `Start-Job -ShowData`, or for jobs referenced +in `Show-JobData`, hook up event handlers on the data stream collections for +the job objects to capture the data from the jobs as it is added in real time, +and show that data in the current terminal with the job name or ID in front of +that data. Mirror how `ProgressInformation` is rendered when it comes to +showing job data this way. 1. Add a `&!` operator that starts a job with the data display turned on. 1. Add a boolean property to `BackgroundJob` objects called `ShowData` that identifies if the job is currently configured to show data or not. 1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. -1. Add a `-ShowInHost` parameter to `Start-Job` that sets `ShowData` to true +1. Add a `-ShowData` parameter to `Start-Job` that sets `ShowData` to true and hooks up event handlers as described in the first item in this list. 1. Add a `$!` variable to store the most recently run job (or jobs if multiple jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3 &`). From d195b7462869675563adc2a454b3360009fea606 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Sun, 30 Jun 2019 14:30:45 -0300 Subject: [PATCH 7/9] consistenty on Output instead of Data --- .../RFCNNNN-Improve-Background-Operator.md | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index 059a498e..88422a6a 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -43,11 +43,11 @@ So that I can launch legacy commands in the background more easily, without havi Also, for completeness/functional parity with cmdlets: As a user,
-I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowData` switch
+I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowOutput` switch
So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. As a user,
-I can show or hide the output of running jobs by using new `Show-JobData` and `Hide-JobData` cmdlets
+I can show or hide the output of running jobs by using new `Show-JobOutput` and `Hide-JobOutput` cmdlets
So that I can control the display and monitoring of running jobs without having to muck around with `Receive-Job -Keep`. As a PowerShell contributor,
@@ -69,7 +69,7 @@ So that I can easily run pipelines as jobs in my automation solutions without sh # This command: Get-Process &! # Would return the same output as this command: -Start-Job {Get-Process} -ShowData +Start-Job {Get-Process} -ShowOutput ``` ```output @@ -81,7 +81,7 @@ Id Name PSJobTypeName State HasMoreData Location In addition to the output above, which is the job object created by the command that was invoked, PowerShell would show the output from the job (and any other job) launched this way in an overlay much like the output from Write-Progress, -with the job data from any stream appearing as it is output in the overlay, +with the job output from any stream appearing as it is output in the overlay, prefixed with "[JobName]:" (e.g. [Job1]: ). This overlay would be slightly larger than Write-Progress so that users could see more output from the job in the overlay, and when all jobs sharing output complete the overlay would @@ -146,21 +146,21 @@ Id Name PSJobTypeName State HasMoreData Location 1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... ``` -### Showing or hiding the data from one or more jobs +### Showing or hiding the output from one or more jobs -This allows job data to be shown or hidden on demand for any jobs. +This allows job output to be shown or hidden on demand for any jobs. ```powershell -# Show the data from job ids 1-5 -Show-JobData -Id 1..5 -# Hide the data from job name Job2 -Hide-JobData -Name Job2 -# Show the data for the last job (or jobs) we launched -Show-JobData -Job $! +# Show the output from job ids 1-5 +Show-JobOutput -Id 1..5 +# Hide the output from job name Job2 +Hide-JobOutput -Name Job2 +# Show the output for the last job (or jobs) we launched +Show-JobOutput -Job $! ``` ```output -# As described in the comments above, with the data showing in an overlay +# As described in the comments above, with the output showing in an overlay ``` ### Viewing the process ID for a job @@ -177,18 +177,18 @@ $!.ProcessId ## Specification -1. For jobs invoked with `&!` or `Start-Job -ShowData`, or for jobs referenced -in `Show-JobData`, hook up event handlers on the data stream collections for -the job objects to capture the data from the jobs as it is added in real time, -and show that data in the current terminal with the job name or ID in front of -that data. Mirror how `ProgressInformation` is rendered when it comes to -showing job data this way. -1. Add a `&!` operator that starts a job with the data display turned on. -1. Add a boolean property to `BackgroundJob` objects called `ShowData` that -identifies if the job is currently configured to show data or not. +1. For jobs invoked with `&!` or `Start-Job -ShowOutput`, or for jobs referenced +in `Show-JobOutput`, hook up event handlers on the output stream collections for +the job objects to capture the output from the jobs as it is added in real +time, and show that output in the current terminal with the job name or ID in +front of each output record. Mirror how `ProgressInformation` is rendered when +it comes to showing job output this way. +1. Add a `&!` operator that starts a job with the output display turned on. +1. Add a boolean property to `BackgroundJob` objects called `ShowOutput` that +identifies if the job is currently configured to show output or not. 1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. -1. Add a `-ShowData` parameter to `Start-Job` that sets `ShowData` to true +1. Add a `-ShowOutput` parameter to `Start-Job` that sets `ShowOutput` to true and hooks up event handlers as described in the first item in this list. 1. Add a `$!` variable to store the most recently run job (or jobs if multiple jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3 &`). From c9324964bce158f1a0068ea8785328a8513f28a9 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Wed, 7 Aug 2019 16:22:07 -0300 Subject: [PATCH 8/9] incorporate feedback --- .../RFCNNNN-Improve-Background-Operator.md | 116 +++++++----------- 1 file changed, 46 insertions(+), 70 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index 88422a6a..9cc70cf5 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -33,25 +33,21 @@ I can reference the most recent job(s) launched with `Start-Job` or the `&` back So that I can write my handling of those jobs in a consistent way without the job object or id, using the same variable that is used in bash for the same purpose. As a user,
-I can launch jobs with a new `&!` background operator that will show job progress in an overlay
-So that watch the concurrent progress of multiple background jobs in my host without blocking my console. - -As a user,
-I can use the `&` operator (and the proposed `&!` operator) after the stop parsing sigil (`--%`)
-So that I can launch legacy commands in the background more easily, without having to use `Start-Job`. +I can launch jobs with a new `&!` background operator that will show job stream data in my console
+So that watch the concurrent progress of multiple background jobs in my host when needed without blocking my console. Also, for completeness/functional parity with cmdlets: As a user,
-I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-ShowOutput` switch
+I can see the output of jobs launched with `Start-Job` or `Start-ThreadJob` in my current host by using a new `-Watch` switch
So that I can launch multiple background jobs and watch their concurrent progress in my host without blocking my console. As a user,
-I can show or hide the output of running jobs by using new `Show-JobOutput` and `Hide-JobOutput` cmdlets
+I can show or hide the output of running jobs by using a new `Watch-Job` cmdlet (with `Watch-Job -Off` to stop watching)
So that I can control the display and monitoring of running jobs without having to muck around with `Receive-Job -Keep`. As a PowerShell contributor,
-I can see the process ID associated with any background job by looking at the job members
+I can see the process ID associated with any job by looking at the job members
So that I can more easily attach the Visual Studio debugger to that job when I need to. Last, one describing the existing motivation for the `&` background operator @@ -59,7 +55,7 @@ Last, one describing the existing motivation for the `&` background operator As a user,
I can launch jobs silently with the `&` background operator
-So that I can easily run pipelines as jobs in my automation solutions without showing output. +So that I can easily run pipelines as jobs in my automation solutions without producing output. ## User Experience @@ -69,7 +65,7 @@ So that I can easily run pipelines as jobs in my automation solutions without sh # This command: Get-Process &! # Would return the same output as this command: -Start-Job {Get-Process} -ShowOutput +Start-Job {Get-Process} -Watch ``` ```output @@ -79,14 +75,10 @@ Id Name PSJobTypeName State HasMoreData Location ``` In addition to the output above, which is the job object created by the command -that was invoked, PowerShell would show the output from the job (and any other -job) launched this way in an overlay much like the output from Write-Progress, -with the job output from any stream appearing as it is output in the overlay, -prefixed with "[JobName]:" (e.g. [Job1]: ). This overlay would be slightly -larger than Write-Progress so that users could see more output from the job in -the overlay, and when all jobs sharing output complete the overlay would -disappear after a delay (5 seconds). Progress messages from the jobs would -appear above the output. +that was invoked, PowerShell will monitor any jobs launched this way and show +their stream output in the current console, with the job output from any stream +prefixed with "[JobName]:" (e.g. [Job1]: ). Progress messages from jobs would +appear in textual format in the console. ### Launching a background job quietly and referencing the job with the `$!` variable @@ -130,37 +122,21 @@ Id Name PSJobTypeName State HasMoreData Location The `$!` variable in those two commands returns the jobs that were created with the command before it. -### Launching a legacy command with the stop-parsing sigil and either the `&` or `&!` background operator +### Monitoring the output from one or more jobs -This corrects a limitation with the background operator(s), which currently -treat `&` (and `&!`) as an argument instead when used after the stop-parsing -sigil. +This allows job output monitoring to be turned on or off for any job. ```powershell -./plink.exe" --% $Hostname -l $Username -pw $Password $Command & +# Monitor the output from job ids 1-5 +Watch-Job -Id 1..5 +# Turn off the monitor for the job named Job2 +Watch-Job -Off -Name Job2 +# Monitor the output for the last job (or jobs) we launched +Watch-Job -Job $! ``` ```output -Id Name PSJobTypeName State HasMoreData Location Command --- ---- ------------- ----- ----------- -------- ------- -1 Job1 BackgroundJob Running True localhost Microsoft.PowerShell.Man... -``` - -### Showing or hiding the output from one or more jobs - -This allows job output to be shown or hidden on demand for any jobs. - -```powershell -# Show the output from job ids 1-5 -Show-JobOutput -Id 1..5 -# Hide the output from job name Job2 -Hide-JobOutput -Name Job2 -# Show the output for the last job (or jobs) we launched -Show-JobOutput -Job $! -``` - -```output -# As described in the comments above, with the output showing in an overlay +# As described in the comments above, with the output showing in the console. ``` ### Viewing the process ID for a job @@ -175,42 +151,42 @@ $!.ProcessId # The process id for the background job(s) ``` +In the case of `ThreadJob` instances, `ProcessId` would contain the ID of the +current process. + ## Specification -1. For jobs invoked with `&!` or `Start-Job -ShowOutput`, or for jobs referenced -in `Show-JobOutput`, hook up event handlers on the output stream collections for +1. Define a `Watch-Job` cmdlet with the following syntax: + + ```powershell + Watch-Job [-Name] [-Off] [] + + Watch-Job [-InstanceId] [-Off] [] + + Watch-Job [-Id] [-Off] [] + ``` + + This cmdlet would turn monitoring on/off for jobs. See the next item for + details on what happens when monitoring is on. + +1. For jobs invoked with `&!` or `Start-Job -Watch`, or for jobs referenced +in `Watch-Job`, hook up event handlers on the output stream collections for the job objects to capture the output from the jobs as it is added in real time, and show that output in the current terminal with the job name or ID in -front of each output record. Mirror how `ProgressInformation` is rendered when -it comes to showing job output this way. -1. Add a `&!` operator that starts a job with the output display turned on. -1. Add a boolean property to `BackgroundJob` objects called `ShowOutput` that +front of each output record. Records for all stream types will be shown using +their string representation when monitored this way. +1. Add a `&!` operator that starts a job with monitoring turned on. +1. Add a boolean property to `BackgroundJob` objects called `Watch` that identifies if the job is currently configured to show output or not. 1. Add an integer property to `BackgroundJob` objects called `ProcessId` that identifies the ID of the process where the job is running. -1. Add a `-ShowOutput` parameter to `Start-Job` that sets `ShowOutput` to true +1. Add a `-Watch` parameter to `Start-Job` that sets `Watch` to true and hooks up event handlers as described in the first item in this list. 1. Add a `$!` variable to store the most recently run job (or jobs if multiple jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3 &`). +1. Add the `ProcessId` property to the default output for all jobs. ## Alternate Proposals and Considerations -### Add the process ID to the default output for a background job - -It may seem like a good idea to show the process ID for a background job in the -default tabular output. While this would be convenient, we also have thread -jobs that don't have a process ID, so it is probably better to leave it out for -consistency across all jobs. It is always accessible via the `ProcessID` member -of background jobs regardless. - -### Flip the silent/noisy approach with the operators - -This approach is proposed because we've already shipped the `&` background -operator, with jobs running silent by default. In bash, if you run a command in -the background using the `&` control operator, the output is displayed in the -current terminal. This discrepancy may be confusing to users. If we feel that -the PowerShell `&` background operator should be more consistent with the bash -equivalent, we could make the `&` background operator show output by default -and have the new `&!` background operator run silent. This wouldn't be a -breaking change, but it would change the behavior for any scripts that are -already using the `&` background operator today. +All alternative proposals and considerations identified so far have either been +dismissed or incorporated into the RFC. From ec371c07c9cabd6aabaca2cc89b62eef7266ebf7 Mon Sep 17 00:00:00 2001 From: Kirk Munro Date: Wed, 7 Aug 2019 16:32:37 -0300 Subject: [PATCH 9/9] add consideration for Watch-Job parameters --- 1-Draft/RFCNNNN-Improve-Background-Operator.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/1-Draft/RFCNNNN-Improve-Background-Operator.md b/1-Draft/RFCNNNN-Improve-Background-Operator.md index 9cc70cf5..a1eaa88b 100644 --- a/1-Draft/RFCNNNN-Improve-Background-Operator.md +++ b/1-Draft/RFCNNNN-Improve-Background-Operator.md @@ -188,5 +188,13 @@ jobs are launched at the same time, e.g. `cmd1 & cmd2 & cmd3 &`). ## Alternate Proposals and Considerations -All alternative proposals and considerations identified so far have either been -dismissed or incorporated into the RFC. +### Use transformation attribute instead of three parameter sets for `Watch-Job` + +Instead of using multiple parameter sets, one that accepts a job name, another +that accepts a job instance ID, and a third that accepts a job ID, `Watch-Job` +could be implemented with a single parameter set that accepts a `Job` object, +but that uses a `Job()` transformation attribute to also accept a job name, ID, +or instance ID. This would make for easy pipelining without having to present +so many parameter sets to end users. On the downside, transformation attributes +and the types they support are not discoverable in the default syntax output +for parameters at this time.