proxb / PoshRSJob

Provides an alternative to PSjobs with greater performance and less overhead to run commands in the background, freeing up the console and allowing throttling on the jobs.
MIT License
541 stars 87 forks source link

Preserve jobs order #180

Open MVKozlov opened 6 years ago

MVKozlov commented 6 years ago

Fixes #179.

Changes proposed in this pull request: Job order for Get-RSJob preserved from input to output

How to test this code:

PS C:\> 1..10 | Start-RSJob {
>>     if (1 -BAND $_) {
>>         "First ($_)"
>>     } Else {
>>         Start-sleep -seconds 2
>>         "Last ($_)"
>>     }
>> } | Wait-RSJob | Receive-RSJob
First (1)
First (3)
First (5)
First (7)
First (9)
Last (2)
Last (4)
Last (6)
Last (8)
Last (10)

Has been tested on (remove any that don't apply):

proxb commented 6 years ago

I think I will accept this one after https://github.com/proxb/PoshRSJob/pull/178 has been completed assuming that the OP gets back to my question in a reasonable amount of time.

ChrisMagnuson commented 5 years ago

I know this is a little old but I would like to be able to use the streaming aspect of Wait-RSJob so that as jobs complete I can immediately start another long running single threaded processes so that they are going through that downstream process as soon as they are individually done, not once all of them are done.

MVKozlov commented 5 years ago

so, you want single threading ? may be just not use RSJob ? :) or may be join multiple jobs inside one ?

or, if you want to start the same jobs with different data, then look to -Throttle 1

because Wait-RSJob return Job object, not data

ChrisMagnuson commented 5 years ago

@MVKozlov I am sorry I must not have been clear, I want to process a set of asynchronous jobs as soon as each one is complete.

To do this I would need the streaming functionality that passes whichever jobs have reached completion down the pipeline as soon as the job is complete.

MVKozlov commented 5 years ago

it sounds still not clear to me. let's divide question...

  1. Do you want to run the different jobs each time or the same with different data ? $data1 | { scriptblock-1 } $data2 | { scriptblock-2 } or $data1 | { scriptblock-1 } $data2 | { scriptblock-1 }

  2. Do you want your output from scriptblocks go to into next scriptblock or it is fully independent and just need to be run sequidentally ? $data1 | { scriptblock-1 } | { scriptblock-2 } or $data1 | { scriptblock-1 }, $data2 | { scriptblock-2 }

ChrisMagnuson commented 5 years ago

@MVKozlov I have created some sample code below that I think will help explain.

I believe this is closest to the $data1 | { scriptblock-1 } | { scriptblock-2 } scenario you listed above but it would be more like $data1,$data2 | { scriptblock-1 } | { scriptblock-2 }:

$ArrayOfObjects = [PSCustomObject]@{
    URL1 = "https://domain.com/file83423"
    URL2 = "https://domain.com/file88234"
},
[PSCustomObject]@{
    URL1 = "https://domain.com/file12342"
    URL2 = "https://domain.com/file84342"
}

$ArrayOfObjects | 
Start-RSJob -ScriptBlock { ScriptBlockToDownloadFilesFromURLs } |
Wait-RSJob |
Receive-RSJob |
ForEach-Object -Process {
    #This should be executed the moment any job has downloaded both of its two files    
    ScriptBlockToDoSomethingWithTheTwoFilesPerIndividualJob
    #This should keep being executed as each individual set of two downloaded files is passed to it by jobs that have completed 
    #This happens in whatever order the jobs complete, not in the order of the $ArrayOfObjects
}
MVKozlov commented 5 years ago

ok, now I see. but seems there is no method to accomplish this task, sorry. I have a plans to redesign commands to property support pipeline but have no time just now. and @proxb still not approve previous PRs...

MVKozlov commented 5 years ago

@ChrisMagnuson, fortunately for you, it was a calm morning :)

https://github.com/MVKozlov/PoshRSJob/tree/PerJobTimeout

ChrisMagnuson commented 5 years ago

@MVKozlov Nice!

I cloned this and ran the example from PoshRSJob README.md and now the example works again:

PS > 1..10|Start-RSJob {
>>     if (1 -BAND $_){
>>         "First ($_)"
>>     }Else{
>>         Start-sleep -seconds 2
>>         "Last ($_)"
>>     }
>> }|Wait-RSJob|Receive-RSJob|ForEach{"I am $($_)"}
I am First (1)
I am First (3)
I am First (5)
I am First (7)
I am First (9)
I am Last (2)
I am Last (4)
I am Last (6)
I am Last (8)
I am Last (10)

Will there be another separate PR for this?

MVKozlov commented 5 years ago

I can make as many PR as need but @proxb seems have no time to visit here

ChrisMagnuson commented 5 years ago

@MVKozlov I see what you mean, don't see much activity from @proxb since February.

I will focus on trying to use that branch of your fork in our code for now.