How to Add Delays or Timing Controls Before Step Execution in Probe

Probe provides three distinct mechanisms—waitfields for pre-step pauses,retry.initialDelayfor first-attempt delays, and job-levelrepeat.intervalfor timing between job runs—all backed by Gotime.Durationparsing in thelinyows/probesource code.

When orchestrating complex workflows with Probe, controlling the timing of step execution is essential for rate limiting, service readiness, and resource management. The open-source linyows/probe repository implements granular timing controls through YAML configuration fields that integrate directly with the execution engine. These controls leverage Go's standard time.Duration parsing to support flexible duration specifications from milliseconds to minutes.

Understanding Probe's Timing Control Mechanisms

Probe implements three distinct timing controls that operate at different stages of the execution lifecycle. Each mechanism serves a specific purpose, from pausing before individual actions to spacing out entire job repetitions.

The available controls include:

  • wait field – Pauses execution immediately before a step's action runs
  • retry.initialDelay – Delays the first retry attempt in a retry loop
  • repeat.interval – Controls timing between successive job executions

All three mechanisms accept Go duration strings (e.g., "500ms", "2s", "1m") and are implemented across step.go and executor.go in the repository.

Using the wait Field for Pre-Step Delays

The wait field defines a pause that occurs immediately before a step's action executes, following any skip checks but preceding the actual work. In step.go, the Step.handleWait method parses this value and invokes sleepWithMessage to perform the delay.

Values less than one second trigger silent sleeping, while durations of one second or longer display a spinner suffix each second to maintain UI responsiveness. The implementation resides at lines 514–538 of step.go.

steps:
  - name: "Fetch data"
    uses: http
    with:
      url: https://api.example.com/data
    wait: "2s"   # pause 2 seconds before the HTTP request

For sub-second precision, specify milliseconds:

steps:
  - name: "Health check"
    uses: http
    with:
      url: https://service/health
    wait: "500ms"   # silent 500ms pause

Configuring retry.initialDelay for First-Attempt Timing

When implementing retry logic, the initialDelay field within a retry block specifies how long to wait before the first attempt executes. This differs from the standard interval field, which only controls delays between subsequent retries.

In step.go (lines 145–152), the executeActionWithRetry function explicitly honors retry.InitialDelay.Duration via time.Sleep before initiating the first action attempt.

steps:
  - name: "Upload file"
    uses: sftp
    with:
      src: ./artifact.zip
      dst: /remote/path/
    retry:
      maxAttempts: 5
      interval: "3s"
      initialDelay: "10s"   # wait 10 seconds before the first attempt

This pattern proves particularly useful when connecting to services that require warm-up time or when avoiding thundering herd problems during batch operations.

Job-Level Timing with repeat.interval

For workflows that require multiple executions of the same job sequence, the repeat.interval field controls the sleep duration between complete job runs. This top-level configuration affects the Executor rather than individual steps.

In executor.go (lines 48–55), the sleepBetweenRepeats method checks the job's repeat counters and sleeps for job.Repeat.Interval.Duration, creating consistent pacing across job iterations.

jobs:
  backup:
    repeat:
      total: 3
      interval: "1m30s"   # wait 90 seconds between each full backup run

    steps:
      - name: "Run backup"
        uses: script
        with:
          cmd: "./run-backup.sh"

Combining Multiple Timing Controls

Probe allows simultaneous use of these timing mechanisms, creating layered execution control. When combining controls, the execution order follows the lifecycle: wait triggers first, then initialDelay (if retries are configured), followed by the action itself.

steps:
  - name: "Run health check"
    uses: http
    with:
      url: https://service/health
    wait: "500ms"           # pre-step pause

    retry:
      maxAttempts: 3
      interval: "2s"        # between retries

      initialDelay: "5s"    # before first retry attempt

In this configuration, Probe waits 500 milliseconds before the initial HTTP request. If that request fails, it waits 5 seconds before the first retry, then 2 seconds between subsequent retries.

Summary

  • Probe provides three timing controls: wait fields on steps, retry.initialDelay for retry loops, and repeat.interval for job-level repetition.
  • All duration values use Go's time.Duration parsing, supporting formats like "500ms", "3s", and "2m".
  • The wait field is processed in step.go by handleWait and sleepWithMessage, showing spinners for durations ≥1 second.
  • retry.initialDelay is implemented in step.go's executeActionWithRetry function (lines 145–152).
  • repeat.interval is handled by executor.go's sleepBetweenRepeats method (lines 48–55).
  • Values under one second sleep silently, while longer durations display progress indicators.

Frequently Asked Questions

What duration formats does Probe support for timing controls?

Probe accepts any valid Go time.Duration string, including "500ms" for milliseconds, "3s" for seconds, "2m" for minutes, and "1h" for hours. Legacy integer values like "5" are interpreted as seconds. All parsing uses Go's standard library duration parsing functions.

Where is the wait field processed in the Probe source code?

The wait field is processed in step.go within the Step.handleWait method (lines 514–538). This method parses the duration string and calls sleepWithMessage, which either sleeps silently for sub-second durations or displays a spinner suffix for each second of longer waits.

How does Probe handle waits longer than one second?

When the wait duration equals or exceeds one second, the sleepWithMessage function in step.go prints a spinner suffix to the console each second during the pause. This keeps the terminal UI responsive and indicates that the process is actively waiting rather than frozen.

Can I use both wait and retry.initialDelay in the same step?

Yes, these fields are complementary. The wait field executes immediately before the step's first action attempt, while retry.initialDelay only applies if the step fails and enters the retry loop. If both are configured, Probe executes the wait delay first, attempts the action, and then applies initialDelay before the first retry attempt.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →