Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write to a file with multiple jobs in PowerShell

We have an activity that runs the following code:

$nr = $WorkflowData['_Number']

## Write to text
$nr>>C:\Configuration\nrFile.txt

Basically it gets a unique number that should be added to a file. The problem is that this activity runs in multiple workflows that can run at the same time. This resulted in a lot of errors saying that the nrFile.txt is opened by another job running at the same time.

Is there some way to write from multiple workflows to the same file simultaneously?

Or maybe to queue them up somehow?

like image 682
Aldu Avatar asked Aug 06 '13 15:08

Aldu


2 Answers

You could synchronize file access using a Mutex e.g.

$mutex = new-object System.Threading.Mutex $false,'SomeUniqueName'
...
nr = $WorkflowData['_Number']
$mutex.WaitOne() > $null
$nr >> C:\Configuration\nrFile.txt
$mutex.ReleaseMutex()
like image 100
Keith Hill Avatar answered Sep 19 '22 14:09

Keith Hill


You alternate between saying multiple jobs are trying to access the file, or multiple activities in a workflow. Jobs are isolated into separate processes, so certain contention-prevention mechanisms do not apply. Workflows are run within the same process, so those approaches could be appropriate in that case.

It's not glamorous, but a basic "if at first you don't succeed, try, try again" approach is usually perfectly adequate for something like this.

filter append
{
   param(
       [Parameter(Mandatory = $true, ValueFromPipeline = $true)][string[]] $line,
       [Parameter(Mandatory = $true, Position = 0)][string] $path
   )

   $done = $false
   while(-not $done)
   {
       try{ $line | out-file $path -append -ea Stop }
       catch { sleep 1; continue }
       $done = $true
   }
}

$nr | append C:\Configuration\nrFile.txt

Edit Previously incorrectly asserted that named mutex (Keith's approach) does not work inter-process.

like image 34
latkin Avatar answered Sep 22 '22 14:09

latkin