Private/Sampling.ps1

# How Gatherers sample the Target Machine.
#
# Several Checks average a counter across a window rather than trusting one reading: a
# single spike is not sustained pressure, and a machine is never perfectly still. How many
# readings each Check takes is its own business, but the wait between them is shared, so a
# test performing a real Run can collapse every window at once.
#
# This is deliberately not a Check Definition parameter. A Customer may reasonably
# disagree about a threshold; they have no opinion about how many readings make an average.

$script:SampleIntervalSeconds = 1

function Get-SampleSeconds {
    <#
    .SYNOPSIS
        How long a wait of the given length actually lasts, after the shared interval.
    .DESCRIPTION
        Pure, so a Gatherer can record the window it used and its Section can say so
        rather than claim a window that was collapsed out from under it.
    #>

    [CmdletBinding()]
    [OutputType([double])]
    param([double]$Seconds = 1)

    if ($script:SampleIntervalSeconds -le 0) { return 0 }
    $Seconds * $script:SampleIntervalSeconds
}

function Wait-Sample {
    <#
    .SYNOPSIS
        Waits between two readings of a counter, and emits nothing.
    .DESCRIPTION
        Emitting nothing is load-bearing: this is called inside sampling loops whose
        output is the readings themselves, so anything returned here would be collected
        alongside them and averaged as though it were a measurement.
    .PARAMETER Seconds
        A settle longer than one interval, for a counter that is a rate over a window
        rather than an instant. Scaled by the shared interval rather than ignoring it,
        so collapsing the interval collapses every wait and none is left behind.
    #>

    [CmdletBinding()]
    [OutputType([void])]
    param([double]$Seconds = 1)

    $wait = Get-SampleSeconds -Seconds $Seconds
    if ($wait -gt 0) { Start-Sleep -Seconds $wait }
}