| | | 1 | | <# |
| | | 2 | | .SYNOPSIS |
| | | 3 | | Updates a synchronized counter in a thread-safe manner. |
| | | 4 | | .DESCRIPTION |
| | | 5 | | This function updates a numeric counter stored in a synchronized collection |
| | | 6 | | (such as a synchronized Hashtable or OrderedDictionary) in a thread-safe way. |
| | | 7 | | It uses locking to ensure that increments are atomic and safe for concurrent access. |
| | | 8 | | .PARAMETER Table |
| | | 9 | | The synchronized collection (Hashtable or OrderedDictionary) containing the counter. |
| | | 10 | | .PARAMETER Key |
| | | 11 | | The key in the collection that identifies the counter to update. |
| | | 12 | | .PARAMETER By |
| | | 13 | | The amount to increment the counter by. Default is 1. |
| | | 14 | | .PARAMETER WhatIf |
| | | 15 | | Shows what would happen if the command runs. The command is not executed. |
| | | 16 | | .PARAMETER Confirm |
| | | 17 | | Prompts you for confirmation before running the command. The command is not run unless you respond |
| | | 18 | | affirmatively. |
| | | 19 | | .EXAMPLE |
| | | 20 | | $table = [hashtable]::Synchronized(@{ Visits = 0 }) |
| | | 21 | | Update-KrSynchronizedCounter -Table $table -Key 'Visits' -By 1 |
| | | 22 | | This increments the 'Visits' counter in the synchronized hashtable by 1. |
| | | 23 | | .NOTES |
| | | 24 | | This function is part of the Kestrun.SharedState module and is used to safely update |
| | | 25 | | counters in shared state. |
| | | 26 | | #> |
| | | 27 | | function Update-KrSynchronizedCounter { |
| | | 28 | | [KestrunRuntimeApi('Route')] |
| | | 29 | | [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] |
| | | 30 | | param( |
| | | 31 | | [Parameter(Mandatory)] |
| | | 32 | | [System.Collections.IDictionary]$Table, # Hashtable or OrderedDictionary (synchronized) |
| | | 33 | | |
| | | 34 | | [Parameter(Mandatory)] |
| | | 35 | | [string]$Key, |
| | | 36 | | |
| | | 37 | | [Parameter()] |
| | | 38 | | [int]$By = 1 # default increment is +1 |
| | | 39 | | ) |
| | | 40 | | |
| | 0 | 41 | | $lock = $Table.SyncRoot |
| | | 42 | | |
| | 0 | 43 | | $target = "counter '$Key' in synchronized table" |
| | 0 | 44 | | $action = "Update by $By" |
| | | 45 | | |
| | 0 | 46 | | if (-not $PSCmdlet.ShouldProcess($target, $action)) { |
| | | 47 | | # Return current value (or $null if missing) when -WhatIf / -Confirm says "no" |
| | 0 | 48 | | return $Table[$Key] |
| | | 49 | | } |
| | | 50 | | |
| | 0 | 51 | | [System.Threading.Monitor]::Enter($lock) |
| | | 52 | | try { |
| | 0 | 53 | | if (-not $Table.Contains($Key)) { |
| | 0 | 54 | | $Table[$Key] = 0 |
| | | 55 | | } |
| | | 56 | | |
| | 0 | 57 | | $Table[$Key] = [int]$Table[$Key] + $By |
| | 0 | 58 | | return $Table[$Key] |
| | | 59 | | } finally { |
| | 0 | 60 | | [System.Threading.Monitor]::Exit($lock) |
| | | 61 | | } |
| | | 62 | | } |