Skip to content

Commit

Permalink
Merge pull request #38 from pwsh-cs-tools/perf-v0.4.4
Browse files Browse the repository at this point in the history
Performance: 0.4.4 - Add and Parallelize Temp File Garbage Collection
  • Loading branch information
anonhostpi authored Jan 15, 2024
2 parents 948579d + 2ae7429 commit 733cf47
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 136 deletions.
2 changes: 1 addition & 1 deletion Import-Package/Import-Package.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = '.\Import-Package.psm1'

# Version number of this module.
ModuleVersion = '0.4.3'
ModuleVersion = '0.4.4'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
67 changes: 53 additions & 14 deletions Import-Package/Import-Package.psm1
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
# Initialize - Bootstraps the nuget type system
Write-Verbose "[Import-Package:Init] Initializing..."
$bootstrapper = & (Resolve-Path "$PSScriptRoot\packaging.ps1")
$global:loaded = @{
$loaded = @{
"NuGet.Frameworks" = "netstandard2.0"
}
$mutexes = @{}

& {
# Clear the Cache
Write-Verbose "[Import-Package:Init] Clearing Temp Files..."
Resolve-Path (Join-Path $PSScriptRoot "Temp" "*") | ForEach-Object -Parallel {
$id = $_ | Split-Path -Leaf
[bool] $freed = $false
$m = New-Object System.Threading.Mutex( $false, "Global\ImportPackage-$id", [ref] $freed )
If( $freed ){
Remove-Item $_ -Recurse -ErrorAction Stop
}
$m.Dispose()
} -ThrottleLimit 12 -AsJob | Out-Null
}

. "$PSScriptRoot\src\Resolve-DependencyVersions.ps1";

. "$PSScriptRoot\src\Resolve-DependencyVersions.ps1"
. "$PSScriptRoot\src\Resolve-CachedPackage.ps1"
. "$PSScriptRoot\src\Build-PackageData.ps1"

Write-Verbose "[Import-Package:Init] Initialized"
Expand Down Expand Up @@ -157,11 +174,34 @@ function Import-Package {
[string] $Path,

[switch] $Offline,

# [string] $CachePath = "$PSScriptRoot\Packages"
[string] $TempPath = (& {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
New-Item -ItemType Directory -Path (Join-Path $parent $name)
$parent = & {
[System.IO.Path]::GetTempPath()
# Join-Path ($CachePath | Split-Path -Parent) "Temp"
}
[string] $uuid = [System.Guid]::NewGuid()

# Cut dirname in half by compressing the UUID from base16 (hexadecimal) to base36 (alphanumeric)
$id = & {
$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
}
Write-Verbose "[Import-Package:Directories] UUID $uuid (base16) converted to $compressed (base$( $chars.Length ))"

$compressed
}

$mutexes."$id" = New-Object System.Threading.Mutex($true, "Global\ImportPackage-$id") # Lock the directory from automatic removal

New-Item -ItemType Directory -Path (Join-Path $parent $id) -Force
# Resolve-Path "."
})
)
Expand Down Expand Up @@ -274,11 +314,9 @@ function Import-Package {
} Else {
$TargetFramework
}
} Else {
$TargetFramework
}

If( -not $target_rid_framework ){
Write-Host $PackageData.Name $PackageData.Frameworks.Count $PackageData.RID_Frameworks.Count; pause
$target_rid_framework = $TargetFramework
}

Expand Down Expand Up @@ -348,7 +386,6 @@ function Import-Package {
Write-Verbose "[Import-Package:Loading] Found $( $dlls.lib.Count ) OS-agnostic framework-agnostic dlls"
} Catch {
Write-Verbose "[Import-Package:Loading] Unable to find OS-agnostic framework-agnostic dlls for $($PackageData.Name)"
return
}
If( Test-Path "$(Split-Path $PackageData.Source)\lib\$short_folder_name" ){
Write-Verbose "[Import-Package:Loading] Locating OS-agnostic dlls for $short_folder_name"
Expand All @@ -362,7 +399,6 @@ function Import-Package {
Write-Verbose "[Import-Package:Loading] Found $( $dlls.lib.Count ) OS-agnostic dlls for $short_folder_name"
} Catch {
Write-Verbose "[Import-Package:Loading] Unable to find OS-agnostic dlls for $($PackageData.Name) for $short_folder_name"
return
}
}
}
Expand All @@ -381,7 +417,6 @@ function Import-Package {
Write-Verbose "[Import-Package:Loading] Found $( $native_dlls.Count ) OS-specific native dlls"
} Catch {
Write-Verbose "[Import-Package:Loading] Unable to find OS-specific native dlls for $($PackageData.Name) on $($bootstrapper.runtime)"
return
}
If( Test-Path "$(Split-Path $PackageData.Source)\runtimes\$( $PackageData.RID )\lib\$short_folder_name" ){
Try {
Expand All @@ -394,7 +429,6 @@ function Import-Package {
Write-Verbose "[Import-Package:Loading] Found $( $lib_dlls.Count ) OS-specific managed dlls"
} Catch {
Write-Verbose "[Import-Package:Loading] Unable to find OS-specific managed dlls for $($PackageData.Name) on $($bootstrapper.runtime)"
return
}
}
}
Expand Down Expand Up @@ -447,7 +481,12 @@ function Import-Package {
}
} else {
Write-Warning "[Import-Package:Loading] $($PackageData.Name) is not needed for $( $bootstrapper.Runtime )`:$($TargetFramework.GetShortFolderName())"
return
}

If( Test-Path (Join-Path $TempPath "*") ){
Write-Verbose "[Import-Package:Loading] Temp files: $TempPath"
} Else {
Remove-Item -Path $TempPath -ErrorAction Stop
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Import-Package/packaging.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,4 @@ public static extern IntPtr dlopen(string path, int flags);
$this
}
$Exported.Init()
} # | % { $global:Test = $_ }
}
2 changes: 1 addition & 1 deletion Import-Package/runtimeidentifier.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Try {
} | Where-Object { $_ }

$rids = if( $oses.Count ){
$global:version_ammendments = @(
$version_ammendments = @(
@(
@(
"alpine", "centos", "debian", "fedora", "linuxmint",
Expand Down
131 changes: 12 additions & 119 deletions Import-Package/src/Build-PackageData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,10 @@ function Build-PackageData {
[ValidateSet("Object","Install","File")]
[string] $From,
[Parameter(Mandatory)]
$Options,
$Manifest # Unused will have to be worked out at a later date
<#
The purpose of the manifest will be to modify how Install-Package handles Importing
May need to account for skipping, special conditions, and possibly postload scripts
There have been 3 considerations for where this manifest will be sourced from:
- a .nupkg's .psd1 file
- a .nupkg's .nuspec file
- possibly a separate .json or .ps1 file
#>
$Options
)
$Out = @{

$Defaults = @{
"Name" = "Undefined"
"Version" = "Undefined"
"Source" = "Undefined"
Expand All @@ -33,11 +23,11 @@ function Build-PackageData {
$temp_options = @{}
$Options | ForEach-Object {
$iter_options = $_
$Out.Keys | ForEach-Object {
$Defaults.Keys | ForEach-Object {
$temp_options[ $_ ] = If( $iter_options[ $_ ] ){
$iter_options[ $_ ]
} Elseif( $Out[ $_ ] -ne "Undefined") {
$Out[ $_ ]
} Elseif( $Defaults[ $_ ] -ne "Undefined") {
$Defaults[ $_ ]
}
}
}
Expand All @@ -47,114 +37,17 @@ function Build-PackageData {
$Options
}

switch( $From ){
"Object" {
$out_keys = $Out.Keys | ForEach-Object { $_ }

$out_keys | ForEach-Object {
$Out[ $_ ] = $Options[ $_ ]
}
}
"Install" {

$package_attempts = @{}

$package_attempts.local_latest = Get-Package $Options.Name -ProviderName NuGet -ErrorAction SilentlyContinue

$version_available = Try{
If( $Options.Version ){
$Options.Version
} Elseif( $Options.Offline ) {
$package_attempts.local_latest.Version
} Else {
$Bootstrapper.GetLatest( $Options.Name )
}
} Catch {
$package_attempts.local_latest.Version
}

$install_conditions = @(
(-not $package_attempts.local_latest), # Package not Installed
($package_attempts.local_latest.Version -ne $version_available ) # Package either not up to date, or isn't required version
)

if( $install_conditions ){

$version_wanted = $version_available # For the purpose of self-documenting code

$package_attempts.local_corrected_ver = Try {

# Check if the wanted version exists in the old version cache
Get-Package $Options.Name -RequiredVersion $version_wanted -ProviderName NuGet -ErrorAction Stop
}
Catch {

# If it doesn't install it:
Write-Verbose "[Import-Package:Preparation] Installing $( $Options.Name ) $version_wanted"
Try {
Install-Package $Options.Name `
-ProviderName NuGet `
-RequiredVersion $version_wanted `
-SkipDependencies `
-Force `
-ErrorAction Stop | Out-Null
} Catch {
Install-Package $Options.Name `
-ProviderName NuGet `
-RequiredVersion $version_wanted `
-SkipDependencies `
-Scope CurrentUser `
-Force | Out-Null
}
Resolve-CachedPackage -From $From -Options $Options -Bootstrapper $Bootstrapper

# Error check it and return it:
Get-Package $Options.Name -RequiredVersion $version_wanted -ProviderName NuGet -ErrorAction Stop
}
}

If( $package_attempts.local_corrected_ver ){
$Options.Version = $package_attempts.local_corrected_ver.Version
$Options.Source = $package_attempts.local_corrected_ver.Source
} Else {
$Options.Version = $package_attempts.local_latest.Version
$Options.Source = $package_attempts.local_latest.Source
}

$out_keys = $Out.Keys | ForEach-Object { $_ }

$out_keys | ForEach-Object {
$Out[ $_ ] = $Options[ $_ ]
}
}
"File" {
$Options.Unmanaged = $true
$Options.Offline = $true

# This needs to be corrected by the .nuspec, if it is specified in the nuspec
# Additionally, if the version is specifed in the .nuspec, it needs to be provided here
$Options.Name = (Split-Path $Options.Source -Leaf)

# Unpack the package to the TempPath temporary directory
[System.IO.Compression.ZipFile]::ExtractToDirectory( $Options.Source.ToString(), $Options.TempPath.ToString() )
# Copy the nupkg to the temporary directory as well
Copy-Item -Path $Options.Source.ToString() -Destination $Options.TempPath.ToString() -Force

$Options.Source = Join-Path $Options.TempPath.ToString() (Split-Path $Options.Source -Leaf)

$out_keys = $Out.Keys | ForEach-Object { $_ }

$out_keys | ForEach-Object {
$Out[ $_ ] = $Options[ $_ ]
}
}
}
$Out = @{}

$out_keys = $Out.Keys | ForEach-Object { $_ }
$default_keys = $Defaults.Keys | ForEach-Object { $_ }

$out_keys | ForEach-Object {
If( "$($Out[ $_ ])" -eq "Undefined" ){
$default_keys | ForEach-Object {
If( "$($Defaults[ $_ ])" -eq "Undefined" ){
$Out[ $_ ] = $Null
}
$Out[ $_ ] = $Options[ $_ ]
}

<#
Expand Down
Loading

0 comments on commit 733cf47

Please sign in to comment.