Merge pull request #276 from PetriAsi/feature/throttlerequests

Feature/throttlerequests
This commit is contained in:
Petri Asikainen 2022-08-08 13:59:43 +03:00 committed by GitHub
commit 381b6e3586
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 1 deletions

View file

@ -118,6 +118,58 @@ function Invoke-SnipeitMethod {
Write-Debug "$($Body | ConvertTo-Json)"
#Check throttle limit
if ($SnipeitPSSession.throttleLimit -gt 0) {
Write-Verbose "Check for request throttling"
Write-debug "ThrottleMode: $($SnipeitPSSession.throttleMode)"
Write-debug "ThrottleLimit: $($SnipeitPSSession.throttleLimit)"
Write-debug "ThrottlePeriod: $($SnipeitPSSession.throttlePeriod)"
Write-debug "ThrottleThreshold: $($SnipeitPSSession.throttleThreshold)"
Write-debug "Current count: $($SnipeitPSSession.throttledRequests.count)"
#current request timestamps in period
$SnipeitPSSession.throttledRequests = ($SnipeitPSSession.throttledRequests).where({$_ -gt (get-date).AddMilliseconds( 0 - $SnipeitPSSession.throttlePeriod).ToFileTime()})
#make sure that we alway have list here
if($null -eq $SnipeitPSSession.throttledRequests) {
$SnipeitPSSession.throttledRequests = [System.Collections.ArrayList]::new()
}
$naptime = 0
switch ($SnipeitPSSession.throttleMode) {
"Burst" {
if ($SnipeitPSSession.throttledRequests.count -ge $SnipeitPSSession.throttleLimit) {
$naptime = [Math]::Round(((get-date).ToFileTime() - ($SnipeitPSSession.throttledRequests[0]))/10000)
}
}
"Constant" {
$prevrequesttime =[Math]::Round(((get-date).ToFileTime() - ($SnipeitPSSession.throttledRequests[$SnipeitPSSession.throttledRequests.count - 1]))/10000)
$naptime = [Math]::Round($SnipeitPSSession.throttlePeriod / $SnipeitPSSession.throttleLimit) - $prevrequesttime
}
"Adaptive" {
$unThrottledRequests = $SnipeitPSSession.throttleLimit * ($SnipeitPSSession.throttleThreshold / 100)
if($SnipeitPSSession.throttledRequests.count -ge $unThrottledRequests) {
#calculate time left in throttlePeriod and devide it for remaining requests
$remaining = $SnipeitPSSession.throttleLimit - $SnipeitPSSession.throttledRequests.count
if ($remaining -lt 1) {
$remaining = 1
}
$naptime = [Math]::Round((((get-date).ToFileTime() - ($SnipeitPSSession.throttledRequests[0]))/ 10000) / $remaining)
}
}
}
#Do we need a nap
if ($naptime -gt 0) {
Write-verbose "Throttling request for $naptime ms"
Start-Sleep -Milliseconds $naptime
}
$SnipeitPSSession.throttledRequests.Add((Get-Date).ToFileTime())
}
# Invoke the API
try {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Invoking method $Method to URI $URi"

View file

@ -20,6 +20,22 @@
PSCredential where username shoul be snipe it url and password should be
snipe it apikey.
.PARAMETER throttleLimit
Throttle request rate to nro of requests per throttlePeriod. Defaults to 0 that means no requests are not throttled.
.PARAMETER throttlePeriod
Throttle period time span in milliseconds defaults to 60 milliseconds.
.PARAMETER throttleThreshold
Threshold percentage of used request on period after request are throttled.
.PARAMETER throttleMode
RequestThrottling type. "Burst" allows all requests to be used in ThrottlePeriod without delays and then waits
until there's new requests avalable. With "Contant" mode there always delay between requests. Delay is calculated
by dividing throttlePeriod with throttleLimit. "Adaptive" mode allows throttleThreshold percentage of request to be
used with out delay, after threshold limit is reached next requests are delayded by dividing available requests
over throttlePeriod.
.EXAMPLE
Connect-SnipeitPS -Url $url -apiKey $myapikey
Connect to Snipe it api.
@ -61,7 +77,28 @@ function Connect-SnipeitPS {
[SecureString]$secureApiKey,
[Parameter(ParameterSetName='Connect with credential',Mandatory=$true)]
[PSCredential]$siteCred
[PSCredential]$siteCred,
[Parameter(ParameterSetName='Connect with url and apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with url and secure apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with credential',Mandatory=$false)]
[int]$throttleLimit,
[Parameter(ParameterSetName='Connect with url and apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with url and secure apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with credential',Mandatory=$false)]
[int]$throttlePeriod,
[Parameter(ParameterSetName='Connect with url and apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with url and secure apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with credential',Mandatory=$false)]
[int]$throttleThreshold,
[Parameter(ParameterSetName='Connect with url and apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with url and secure apikey',Mandatory=$false)]
[Parameter(ParameterSetName='Connect with credential',Mandatory=$false)]
[ValidateSet("Burst","Constant","Adaptive")]
[string]$throttleMode
)
@ -86,6 +123,21 @@ function Connect-SnipeitPS {
$SnipeitPSSession.apiKey = $siteCred.GetNetworkCredential().SecurePassword
}
}
if($null -eq $throttleLimit) { $throttleLimit = 0}
$SnipeitPSSession.throttleLimit = $throttleLimit
if($throttleThreshold -lt 1) { $throttleThreshold = 90}
$SnipeitPSSession.throttleThreshold = $throttleThreshold
if('' -eq $throttleMode) { $throttleMode = "Burst"}
$SnipeitPSSession.throttleMode = $throttleMode
if ($SnipeitPSSession.throttleLimit -gt 0) {
if($null -eq $throttlePeriod) { $throttlePeriod = 60000}
$SnipeitPSSession.throttlePeriod = $throttlePeriod
$SnipeitPSSession.throttledRequests = [System.Collections.ArrayList]::new()
}
Write-Debug "Site-url $($SnipeitPSSession.url)"
Write-Debug "Site apikey: $($SnipeitPSSession.apiKey)"