Closed Silex closed 1 month ago
Hi @Silex,
The most performant way without switching to C# code is probably to use runspaces via a module like Microsoft.PowerShell.ThreadJob
which gives you the Start-ThreadJob
command. It works similar to the Start-Job
command but with less overhead since it runs in the same process in another runspace vs launching a new powershell process and running in a separate process and runspace.
Under most circumstances I haven't actually seen multithreading increase throughput enough to justify the added complexity. It seems like the management server serializes a lot of requests regardless of whether they're coming through the same WCF channel or unique WCF channels. But I haven't dug that deep into parallel performance for a couple of years so your mileage may vary.
I tried the following just now, and it just seems like the requests are deadlocked - they never complete.
$jobs = Get-VmsCamera | Get-VmsCameraStream -Enabled | % {
Start-ThreadJob -ArgumentList $_ {
param($stream)
$stream | Set-VmsCameraStream -Settings @{ FPS = 0.3 }
}
}
$jobs | Receive-Job -Wait -AutoremoveJob
This seems not to deadlock, but it's not faster on my small test setup with 48 total streams available on a handful of cameras. One of the drawbacks is the 1-second import time for the module since each runspace starts from scratch, even if it's running as a thread in-process.
Get-VmsCamera | % {
Start-ThreadJob -ArgumentList $_ {
param($cam)
ipmo milestonepstools
$cam | Get-VmsCameraStream | Set-VmsCameraStream -Settings @{ FPS = '0.21' }
}
} | Receive-Job -Wait -AutoRemoveJob
Well, I thought you needed multiple processes (not threads) as MilestonePSTools is not threadsafe/rentrant (#45).
Anyway you're probably right that the server will likely sequentialize requests anyway so speed increase will be minimal.
On a side note a found a weird typo for "Set-AdaptiveStreaming" on the website:
It says the file is named "Group-CamerasByModel.ps1" :-)
Typo fixed, thanks! And yeah you don't necessarily want to use Connect-Vms
or Connect-ManagementServer
in multiple runspaces in the same process, but technically you can use runspaces and do some work in parallel. Once you import the module in another runspace, that runspace is already "connected" because commands will reuse the singleton [MilestonePSTools.Connection.MilestoneConnection]::Instance
.
The Get-VmsCameraReport
command is an example of a command heavily using runspaces, though I'm not necessarily proud of the implementation. There's still limited value in my experience though when most of the commands are hitting the management server rather than branching out to query the recording server RecorderStatusService2
API for example.
Hello,
I wondered what would be the simplest way to get parallelism, ideally something like this:
Currently I'm using a for loop on each camera, and I cannot help but feel this should be parallelizable...