1
votes

I have written a ScriptBlock that POSTs file uploads to a custom http server and saves the response to disk. It is intended to be used for testing said server and in addition to checking the correct response I'd like to run it in parallel to load the server.

The code in the ScriptBlock was built as separate ps1 script and works. I have then transplanted it into a framework-script using Start-Job for managing the jobs and eventually presenting overall results.

Unfortunately it does not work after that transplantation.

The symptom is that using Start-Job the job never finishes. For testing I have switched to Invoke-Command. A simple Invoke-Command works, InvokeCommand -AsJob does not.

Works:

Invoke-Command -Scriptblock $ScriptBlock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"

Do not work:

Invoke-Command -AsJob -Computer localhost -Scriptblock $ScriptBlock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"
Start-Job -Name $Name -ScriptBlock $Scriptblock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"

The ScriptBlock being used is rather longish. It starts off by declaring Parameters:

$Scriptblock = {
    Param (
        [string]$JobName,
        [string]$path,
        [string]$BASEJOBNAME
    )

And further down uses HttpWebRequest and a few other .NET classes:

$url = "http://localhost:8081/fillandflatten"
[System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create($url)
...
$xfabuffer = [System.IO.File]::ReadAllBytes("$path\$BASEJOBNAME.xml")
...
$header = "--$boundary`r`nContent-Disposition: form-data; name=`"xfa`"; filename=`"xfa`"`r`nContent-Type: text/xml`r`n`r`n"
$buffer = [Text.Encoding]::ascii.getbytes($header)        
...
[System.Net.httpWebResponse] $res = $req.getResponse()

As described when using Start-Job or Invoke-Command -AsJob the child job started simply remains in Running state forever.

What can cause this behaviour? What can be used to debug it? If there is some error can I force the child-job to terminate and tell me what it does not like?

I am using PowerShell 2.0 on Windows XP.

In the framework I came up with I do the Start-Job (currently just one of them, but I plan to ramp up that number for stress-testing). Then I have a loop waiting for them all to terminate:

do {
    $Jobs = @(Get-Job | Where { $_.State -eq "Running" -and $_.Name.StartsWith($BASEJOBNAME) }); 
    $n = $Jobs.Count
    if ($n -gt 0)
    {
        Log -message "Waiting for $n jobs to finish..."    
        Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } | Format-Table -AutoSize -Property Id,Name,State,HasMoreData,Location

        start-Sleep -Seconds 3
    }
} until ($n -eq 0) 

This produces output of the form:

2014-08-01 18:58:52 - Waiting for 1 jobs to finish...

Id Name     State HasMoreData Location
-- ----     ----- ----------- --------
2 XFA001 Running        True localhost

Forever.

A full minimal test-case is:

# Code for the Jobs:
$Scriptblock = {
    [System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create("http://locahost/index.html")        
    return "done"       
}

# Start a job. Three variants, The Job-based ones hang.

# Invoke-Command -Scriptblock $ScriptBlock
#Invoke-Command -AsJob -Computer localhost -Scriptblock $ScriptBlock
$Job = Start-Job -Name $Name -ScriptBlock $Scriptblock

## The rest of the code is only applicable for the Start-Job-Variant

# Wait for all Jobs to finish
do {
    $Jobs = @(Get-Job | Where { $_.State -eq "Running" }); 
    $n = $Jobs.Count
    if ($n -gt 0)
    {
        Write-Host "Waiting for $n jobs to finish..."    
        Get-Job | Format-Table -AutoSize -Property Id,Name,State,HasMoreData
        Start-Sleep -Seconds 3
    }
} until ($n -eq 0) 

# Get output from all jobs
$Data = ForEach ($Job in (@(Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } ))) {  
    Receive-Job $Job
}

# Clean out all jobs
ForEach ($Job in (@(Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } ))) {  
    Remove-Job $Job
}

# Dump output
Write-Host "Output data:"
$Data | Format-Table
Write-Host ""

This hangs for me. If I comment out the line creating the WebRequest object it works.

Thank you.

1
Update: By commenting out stuff from the ScriptBlock I found that it is the creation of the WebRequest that hangs: [System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create($url)Marian Aldenhövel
Edited to add complete minimal testcase.Marian Aldenhövel
Works on Windows 7, fails on XP. I think that settles the case.Marian Aldenhövel

1 Answers

0
votes

When you run Get-Job , does the job's "HasMoreData" properties is "True" ?

If yes, check the output of the job :

Receive-Job <JobName or JobID> -Keep