Skip to content

Commit

Permalink
Add Tasks/RepeatRedis
Browse files Browse the repository at this point in the history
  • Loading branch information
nightroman committed Jan 26, 2025
1 parent 8fb540f commit 3d338fb
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions Tasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Custom tasks may be defined literally and via custom parameters, see [Repeat](Re
- [File](File) shows the custom task `file`, an incremental task with simplified syntax, somewhat similar to Rake's `file`.
- [Repeat](Repeat) shows the custom task `repeat` which is invoked periodically in a build script (schedule) with such tasks.
- [Repeat2](Repeat2) shows the alternative way with using the special command `repeat` which turns tasks into repeatable.
- [RepeatRedis](RepeatRedis) is similar to `Repeat2` but it uses Redis for task records instead of CLIXML files.
- [Retry](Retry) shows the custom task `retry` which retries its action on failures several times depending on parameters.

## Known issues
Expand Down
10 changes: 10 additions & 0 deletions Tasks/RepeatRedis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

This demo is similar to [Repeat2](../Repeat2) but it uses Redis for task records instead of CLIXML files.
This requires [FarNet.Redis](https://www.powershellgallery.com/packages/FarNet.Redis).

[Repeat.tasks.ps1](Repeat.tasks.ps1) defines `repeat` parameters.
It is designed for using in any build script, not just this demo.

The build script [Repeat.build.ps1](Repeat.build.ps1) shows repeat-tasks.

See also [Repeat](../Repeat).
31 changes: 31 additions & 0 deletions Tasks/RepeatRedis/Repeat.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<#
.Synopsis
Example of repeat-tasks.
.Description
See "Repeat.tasks.ps1" for the details of `repeat`.
.Example
Invoke-Build * Repeat.build.ps1
This command checks all repeat-tasks and invokes some of them as needed.
The script is supposed to be invoked periodically, manually or scheduled.
#>

# Import helpers and specify the task prefix.
. .\Repeat.tasks.ps1 temp:repeat:test-repeat-tasks:

# Synopsis: Repeat every minute.
task task1 (repeat 0:1 {
"Doing $($Task.Name)..."
})

# Synopsis: Repeat every hour.
task task2 (repeat 1:0 {
"Doing $($Task.Name)..."
})

# Synopsis: Repeat every day.
task task3 (repeat 1:0:0:0 {
"Doing $($Task.Name)..."
})
84 changes: 84 additions & 0 deletions Tasks/RepeatRedis/Repeat.tasks.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<#
.Synopsis
Defines repeat-task parameters `repeat` using Redis.
.Description
Build scripts dot-source this script in order to use `repeat`.
Repeat-tasks are invoked periodically with specified periods.
Normal task parameters:
- Name, Inputs, Outputs, Partial
Custom repeat parameters:
- Span -- task period
- Jobs -- task jobs
- If -- task condition
Script scope names:
Alias: repeat -- makes repeat-tasks parameters
Variables: $db -- Redis database, used internally but may be used by tasks as well
Functions: New-Repeat, Test-Repeat, Complete-Repeat -- used internally
.Parameter RedisTaskPrefix
Specifies Redis prefix for task strings.
.Parameter RedisConfiguration
Optional Redis configuration string.
Default: $env:FARNET_REDIS_CONFIGURATION
#>

param(
[Parameter(Mandatory=1)]
[string]$RedisTaskPrefix
,
[string]$RedisConfiguration
)

if (!$WhatIf) {
Import-Module FarNet.Redis
$db = Open-Redis -Configuration $RedisConfiguration
}

# "DSL" for scripts.
Set-Alias repeat New-Repeat

# Creates repeat-task parameters.
function New-Repeat(
[Parameter(Position=0, Mandatory=1)]
[timespan]$Span
,
[Parameter(Position=1)]
[object[]]$Jobs
,
[object]$If=$true
)
{
@{
Jobs = $Jobs
If = {Test-Repeat}
Done = {Complete-Repeat}
Data = @{If = $If; Span = $Span}
}
}

# Works as tasks `If`. The original condition is processed first. If it is true
# then the Redis task key is tested. If it exists then the task is skipped.
function Test-Repeat {
$_ = $Task.Data.If
if ($_ -is [scriptblock]) {
$_ = & $_
}

if ($_) {
!(Get-RedisKey ($RedisTaskPrefix + $Task.Name) -TimeToLive)
}
}

# Works as tasks `Done`, on success sets Redis task string and time to live.
function Complete-Repeat {
$key = $RedisTaskPrefix + $Task.Name
$now = [datetime]::Now.ToString('s')
if (!$Task.Error) {
Set-RedisString $key $now -TimeToLive $Task.Data.Span
}
}

0 comments on commit 3d338fb

Please sign in to comment.