Private/Schedules.ps1
function Get-PodeSchedule { param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Name ) return $PodeContext.Schedules[$Name] } function Start-PodeScheduleRunspace { if ((Get-PodeCount $PodeContext.Schedules) -eq 0) { return } $script = { function Invoke-PodeInternalSchedule($Schedule, $Now) { $Schedule.OnStart = $false $remove = $false # increment total number of triggers for the schedule if ($Schedule.Countable) { $Schedule.Count++ $Schedule.Countable = ($Schedule.Count -lt $Schedule.Limit) } # check if we have hit the limit, and remove if (($Schedule.Limit -ne 0) -and ($Schedule.Count -ge $Schedule.Limit)) { $remove = $true } # trigger the schedules logic try { $parameters = @{ Event = @{ Lockable = $PodeContext.Lockable } } foreach ($key in $Schedule.Arguments.Keys) { $parameters[$key] = $Schedule.Arguments[$key] } Add-PodeRunspace -Type Schedules -ScriptBlock (($Schedule.Script).GetNewClosure()) -Parameters $parameters -Forget } catch { $_ | Write-PodeErrorLog } # reset the cron if it's random $Schedule.Crons = Reset-PodeRandomCronExpressions -Expressions $Schedule.Crons return $remove } function Remove-PodeInternalSchedules([string[]] $Schedules) { # add any schedules to remove that have exceeded their end time $Schedules += @($PodeContext.Schedules.Values | Where-Object { (($null -ne $_.EndTime) -and ($_.EndTime -lt $_now)) }).Name if (($null -eq $Schedules) -or ($Schedules.Length -eq 0)) { return } # remove any schedules foreach ($name in $Schedules) { if ($PodeContext.Schedules.ContainsKey($name)) { $PodeContext.Schedules.Remove($name) | Out-Null } } } # select the schedules that trigger on-start $_remove = @() $_now = [DateTime]::Now $PodeContext.Schedules.Values | Where-Object { $_.OnStart } | ForEach-Object { if (Invoke-PodeInternalSchedule -Schedule $_ -Now $_now) { $_remove += $_.Name } } # remove any schedules Remove-PodeInternalSchedules -Schedules $_remove # first, sleep for a period of time to get to 00 seconds (start of minute) Start-Sleep -Seconds (60 - [DateTime]::Now.Second) while ($true) { $_remove = @() $_now = [DateTime]::Now # select the schedules that need triggering $PodeContext.Schedules.Values | Where-Object { (($null -eq $_.StartTime) -or ($_.StartTime -le $_now)) -and (($null -eq $_.EndTime) -or ($_.EndTime -ge $_now)) -and (Test-PodeCronExpressions -Expressions $_.Crons -DateTime $_now) } | ForEach-Object { if (Invoke-PodeInternalSchedule -Schedule $_ -Now $_now) { $_remove += $_.Name } } # remove any schedules Remove-PodeInternalSchedules -Schedules $_remove # cron expression only goes down to the minute, so sleep for 1min Start-Sleep -Seconds (60 - [DateTime]::Now.Second) } } Add-PodeRunspace -Type 'Main' -ScriptBlock $script } |