Skip to content

Instantly share code, notes, and snippets.

@anonhostpi
Created January 18, 2024 10:49
Show Gist options
  • Save anonhostpi/131ff50d0ab648daaf64d2aaa98e160f to your computer and use it in GitHub Desktop.
Save anonhostpi/131ff50d0ab648daaf64d2aaa98e160f to your computer and use it in GitHub Desktop.
Temporary path generation and garbage collection
# Scope table for the module
$scope = @{}
$scope.mname = "TempPathModule"
$scope.parent_path = @(
[System.IO.Path]::GetTempPath()
$scope.mname
) | Join-Path
$scope.mutexes = @{}
# Enforce the Parent Path for the module's temporary paths
New-Item -ItemType Directory -Path $scope.parent_path -Force
function New-TempPath{
param(
[string] $Name
)
$tempname = $Name
While( Test-Path $tempname ){
[string] $uuid = [System.Guid]::NewGuid()
$bigint = [uint128]::Parse( $uuid.ToString().Replace("-",""), 'AllowHexSpecifier')
$compressed = ""
# Make hex-string more compressed by encoding it in base36 (alphanumeric)
$chars = "0123456789abcdefghijklmnopqrstuvwxyz"
While( $bigint -gt 0 ){
$remainder = $bigint % 36
$compressed = $chars[$remainder] + $compressed
$bigint = $bigint/36
}
$tempname = $compressed
}
$ammend_name_condition = `
(-not [string]::IsNullOrWhiteSpace( $Name ) ) -and `
$Name -ne $tempname
If( $ammend_name_condition ){
$Name = "$Name-$tempname"
}
$scope.mutexes."$Name" = New-Object System.Threading.Mutex($true, "Global\$( $scope.mname )-$Name") # Lock the directory from automatic removal
$path = @(
$scope.parent_path,
$Name
) | Join-Path
New-Item -ItemType Directory -Path $path -Force
}
# Garbage Collector - can only clear:
# - garbage from this session or
# - (-AllUnused) all unused garbage from all sessions
function Clear-TempPaths {
param(
[Alias("Name")]
[string] $Id,
[switch] $AllUnused
)
# Clear the TempPath from any unused directories
If( $AllUnused ){
Resolve-Path (Join-Path $scope.parent_path "*") | ForEach-Object -Parallel {
$Id = $_ | Split-Path -Leaf
[bool] $freed = $false
# Check if the directory is still in use, by checking its Mutex
$m = New-Object System.Threading.Mutex( $false, "Global\$( $scope.mname )-$id", [ref] $freed )
If( $freed ){
Remove-Item $_ -Recurse -ErrorAction Stop
}
$m.Dispose()
} -ThrottleLimit 12 -AsJob | Out-Null
} Elseif( @( $scope.mutexes.Keys ) -contains $Id ){
$path = (Join-Path $scope.parent_path $Id)
If( Test-Path $path ){
Remove-Item $path -Recurse -ErrorAction Stop
}
$scope.mutexes."$Id".Dispose()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment